<!DOCTYPE HTML>
<html lang="en">
<head>
<title>Spring Vault Reference Documentation - Spring Vault - Reference Documentation | Docs4dev</title>
<meta charset="UTF-8">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<meta name="description" content="Spring Vault provides familiar Spring abstractions and client-side support for accessing, storing and revoking secrets. It offers both low-level and high-level abstractions for interacting with Vault, freeing the user from infrastructural concerns.">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="true">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta property="og:type" content="website">
<meta property="og:title" content="Spring Vault Reference Documentation - Spring Vault - Reference Documentation">
<meta property="og:url" content="https://www.docs4dev.com/docs/en/spring-vault/2.2.2.RELEASE/reference/">
<meta property="og:site_name" content="Docs4dev">
<meta property="og:locale" content="zh_CN">
<meta name="twitter:card" content="Spring Vault provides familiar Spring abstractions and client-side support for accessing, storing and revoking secrets. It offers both low-level and high-level abstractions for interacting with Vault, freeing the user from infrastructural concerns.">
<meta name="generator" content="Docs4dev template engine">
<link rel="stylesheet" href="static/css/app.min.css">
<link rel="shortcut icon" href="https://www.docs4dev.com/static/images/favicon.ico" type="image/x-icon">
<script async="" src="static/js/js.js"></script>
<script async="" src="static/js/adsbygoogle.js" crossorigin="anonymous"></script>
<script>
    window.dataLayer = window.dataLayer || [];

    function gtag() {
      dataLayer.push(arguments);
    }

    gtag('js', new Date());
    gtag('config', 'UA-129571937-1');
  </script>
<link rel="amphtml" href="https://www.docs4dev.com/amp/docs/en/spring-vault/2.2.2.RELEASE/reference/index.html">

<script type="application/ld+json">{"name":null,"headline":"Spring Vault Reference Documentation-Spring Vault - Reference Documentation","inLanguage":"en-US","version":"2.2.2.RELEASE","image":"/static/icon/icon-spring-framework.svg","datePublished":"2021-05-23T04:01:11Z","dateCreated":"2021-05-23T04:01:11Z","dateModified":"2021-07-05T13:59:29Z","@context":"https://schema.org/","@type":"APIReference","abstract":"Spring Vault provides familiar Spring abstractions and client-side support for accessing, storing and revoking secrets. It offers both low-level and high-level abstractions for interacting with Vault, freeing the user from infrastructural concerns."}</script>
</head>
<body>
<div class="book with-summary">
<div class="book-summary">
<div class="logo">
<a href="javascript:window.open('https://www.docs4dev.com/docs/en/spring-vault/2.2.2.RELEASE/reference');" style="color: inherit;">
<img src="static/picture/icon-spring-framework.svg" style="width: 48px; height: 48px;" alt="Logo">
</a>
<b style="color: inherit; margin-left: 8px;">Spring Vault Reference Documentation</b>
</div>
<div class="item">
<div>
<label for="version">版本</label>
<select id="version" onchange="onVersionChange(this)">
<option value="2.2.2.RELEASE" selected="selected">2.2.2.RELEASE</option>
</select>
</div>

</div>
<div class="item menus">
<a title="Table of Contents" style="margin-right: 8px;" href="#">
<i class="fa fa-chevron-left"></i>
<span style="margin-left: 2px;">返回目录</span>
</a>
</div>
<nav role="navigation" id="navigation">
<div id="toc"></div>
</nav>
</div>
<div class="book-body">
<div class="body-inner">
<header class="book-header">
<div class="dropdown pull-right js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-globe"></i>
</a>
<div class="dropdown-menu dropdown-left">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('zh_CN')">中文</button>
</div>
<div class="buttons">
<button class="button size-1" onclick="changeLang('en_US')">English</button>
</div>
</div>
</div>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign up" href="register.html">
<i class="fa fa-sign-in"></i> <span>注册</span>
</a>
<a class="btn pull-right js-toolbar-action non-mobile" aria-label="Sign in" href="register.html">
<i class="fa fa-sign-in"></i>
<span>登录</span>
</a>
<a class="btn pull-left js-toolbar-action btn-summary" href="#"><i class="fa fa-align-justify"></i></a>
<div class="dropdown pull-left font-settings js-toolbar-action">
<a class="btn toggle-dropdown" aria-label="Font Settings" href="#">
<i class="fa fa-font"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<button class="button size-2 font-reduce">A</button>
<button class="button size-2 font-enlarge">A</button>
</div>
<div class="buttons">
<button class="button size-2 family-serif">Serif</button>
<button class="button size-2 family-sans">Sans</button>
</div>
<div class="buttons">
<button class="button size-3 theme-white">White</button>
<button class="button size-3 theme-sepia">Sepia</button>
<button class="button size-3 theme-night">Night</button>
</div>
</div>
</div>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
<a class="btn pull-left js-toolbar-action non-mobile" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
<div class="dropdown pull-left js-toolbar-action mobile">
<a class="btn toggle-dropdown" aria-label="Language" href="#">
<i class="fa fa-chevron-down"></i>
</a>
<div class="dropdown-menu dropdown-right">
<div class="dropdown-caret"><span class="caret-outer"></span><span class="caret-inner"></span></div>
<div class="buttons">
<a class="button size-1" aria-label="Home" href="en.html">
<i class="fa fa-home"></i> <span>首页</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Guide" href="javascript:window.open('https://www.javadoc.org/');">
<i class="fa fa-book"></i> <span>API Docs</span>
</a>
</div>
<div class="buttons">
<a class="button size-1" aria-label="Tools" href="index37.html">
<i class="fa fa-gears"></i> <span>工具</span>
</a>
</div>
</div>
</div>
<div id="autocomplete" class="pull-right"></div>
<span id="toolbar-title"></span>
</header>
<div class="page-wrapper" tabindex="-1" role="main">
<div class="page-inner">
<section class="normal markdown-section">
<div id="content">
<h1>Spring Vault - Reference Documentation</h1>
<div><ins class="adsbygoogle" style="display:block; text-align:center;" data-ad-layout="in-article" data-ad-format="fluid" data-ad-client="ca-pub-6108808167664152" data-ad-slot="6964403648"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
<div><div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>© 2016-2020 The original authors.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> <em>Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.</em> </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<h2 id="preface" class="sect0"><a class="anchor" href="#preface"></a>Preface</h2>
<div class="openblock partintro">
<div class="content">
<div class="paragraph">
<p>The Spring Vault project applies core Spring concepts to the development of solutions using HashiCorp Vault. We provide a "template" as a high-level abstraction for storing and querying documents. You will notice similarities to the REST support in the Spring Framework.</p>
</div>
<div class="paragraph">
<p>This document is the reference guide for Spring Vault. It explains Vault concepts and semantics and the syntax.</p>
</div>
<div class="paragraph">
<p>This part of the reference documentation explains the core functionality offered by Spring Vault.</p>
</div>
<div class="paragraph">
<p><a href="#vault.core">Vault support</a> introduces the Vault module feature set.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="1.-Document-Structure">1. Document Structure</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section provides basic introduction to Spring and Vault. It contains details about following development and how to get support.</p>
</div>
<div class="paragraph">
<p>The rest of the document refers to Spring Vault features and assumes the user is familiar with <a href="javascript:window.open('https://www.vaultproject.io/');" target="_blank" rel="noopener noreferrer">HashiCorp Vault <i class="fa fa-external-link"></i></a> as well as Spring concepts.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:first-steps:spring"><a class="anchor" href="#get-started:first-steps:spring"></a>2. Knowing Spring</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Vault uses Spring framework’s <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html');" target="_blank" rel="noopener noreferrer">core <i class="fa fa-external-link"></i></a> functionality, such as <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference//core.html');" target="_blank" rel="noopener noreferrer">IoC <i class="fa fa-external-link"></i></a> container. While it is not important to know the Spring APIs, understanding the concepts behind them is. At a minimum, the idea behind IoC should be familiar for whatever IoC container you choose to use.</p>
</div>
<div class="paragraph">
<p>The core functionality of the Vault support can be used directly, with no need to invoke the IoC services of the Spring Container. This is much like <code class="notranslate">RestTemplate</code> which can be used 'standalone' without any other services of the Spring container. To leverage all the features of Spring Vault document, such as the session support, you will need to configure some parts of the library using Spring.</p>
</div>
<div class="paragraph">
<p>To learn more about Spring, you can refer to the comprehensive (and sometimes disarming) documentation that explains in detail the Spring Framework. There are a lot of articles, blog entries and books on the matter - take a look at the Spring framework <a href="javascript:window.open('https://spring.io/docs');" target="_blank" rel="noopener noreferrer">home page <i class="fa fa-external-link"></i></a> for more information.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="get-started:first-steps:vault"><a class="anchor" href="#get-started:first-steps:vault"></a>3. Knowing Vault</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Security and working with secrets is a concern of every developer working with databases, user credentials or API keys. Vault steps in by providing a secure storage combined with access control, revocation, key rolling and auditing. In short: Vault is a service for securely accessing and storing secrets. A secret is anything that you want to tightly control access to, such as API keys, passwords, certificates, and more.</p>
</div>
<div class="paragraph">
<p>The jumping off ground for learning about Vault is <a href="javascript:window.open('https://www.vaultproject.io/');" target="_blank" rel="noopener noreferrer">www.vaultproject.io <i class="fa fa-external-link"></i></a>. Here is a list of useful resources:</p>
</div>
<div class="ulist">
<ul>
<li> <p>The manual introduces Vault and contains links to getting started guides, reference documentation and tutorials.</p> </li>
<li> <p>The online shell provides a convenient way to interact with a Vault instance in combination with the online tutorial.</p> </li>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/intro/index.html');" target="_blank" rel="noopener noreferrer">HashiCorp Vault Introduction <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/index.html');" target="_blank" rel="noopener noreferrer">HashiCorp Vault Documentation <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
<div class="paragraph">
<p>Spring Vault provides client-side support for accessing, storing and revoking secrets. With <a href="javascript:window.open('https://www.vaultproject.io/');" target="_blank" rel="noopener noreferrer">HashiCorp’s Vault <i class="fa fa-external-link"></i></a> you have a central place to manage external secret data for applications across all environments. Vault can manage static and dynamic secrets such as application data, username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, Consul, AWS and more.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="requirements"><a class="anchor" href="#requirements"></a>4. Requirements</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Vault 2.x binaries requires JDK level 8.0 and above, and <a href="javascript:window.open('https://spring.io/docs');" target="_blank" rel="noopener noreferrer">Spring Framework <i class="fa fa-external-link"></i></a> 5.2.4.RELEASE and above.</p>
</div>
<div class="paragraph">
<p>In terms of Vault, <a href="javascript:window.open('https://www.vaultproject.io/');" target="_blank" rel="noopener noreferrer">Vault <i class="fa fa-external-link"></i></a> at least 0.6.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="5.-Additional-Help-Resources">5. Additional Help Resources</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Learning a new framework is not always straight forward. In this section, we try to provide what we think is an easy to follow guide for starting with Spring Vault module. However, if you encounter issues or you are just looking for advice, feel free to use one of the links below:</p>
</div>
<div class="sect2">
<h3 id="get-started:help"><a class="anchor" href="#get-started:help"></a>5.1. Support</h3>
<div class="paragraph">
<p>There are a few support options available:</p>
</div>
<div class="sect3">
<h4 id="get-started:help:community"><a class="anchor" href="#get-started:help:community"></a>5.1.1. Community Forum</h4>
<div class="paragraph">
<p>Post questions questions regarding Spring Vault on <a href="javascript:window.open('https://stackoverflow.com/questions/tagged/spring-vault');" target="_blank" rel="noopener noreferrer">Stackoverflow <i class="fa fa-external-link"></i></a> to share information and help each other. Note that registration is needed <strong>only</strong> for posting.</p>
</div>
</div>
<div class="sect3">
<h4 id="get-started:help:professional"><a class="anchor" href="#get-started:help:professional"></a>5.1.2. Professional Support</h4>
<div class="paragraph">
<p>Professional, from-the-source support, with guaranteed response time, is available from <a href="javascript:window.open('https://pivotal.io/');" target="_blank" rel="noopener noreferrer">Pivotal Sofware, Inc. <i class="fa fa-external-link"></i></a>, the company behind Spring Vault and Spring.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="get-started:up-to-date"><a class="anchor" href="#get-started:up-to-date"></a>5.2. Following Development</h3>
<div class="paragraph">
<p>For information on the Spring Vault source code repository, nightly builds and snapshot artifacts please see the <a href="javascript:window.open('https://projects.spring.io/spring-vault/');" target="_blank" rel="noopener noreferrer">Spring Vault homepage <i class="fa fa-external-link"></i></a>. You can help make Spring Vault best serve the needs of the Spring community by interacting with developers through the Community on <a href="javascript:window.open('https://stackoverflow.com/questions/tagged/spring-vault');" target="_blank" rel="noopener noreferrer">Stackoverflow <i class="fa fa-external-link"></i></a>. If you encounter a bug or want to suggest an improvement, please create a ticket on the Spring Vault issue <a href="javascript:window.open('https://github.com/spring-projects/spring-vault/issues');" target="_blank" rel="noopener noreferrer">tracker <i class="fa fa-external-link"></i></a>. To stay up to date with the latest news and announcements in the Spring ecosystem, subscribe to the Spring Community <a href="javascript:window.open('https://spring.io/');" target="_blank" rel="noopener noreferrer">Portal <i class="fa fa-external-link"></i></a>. Lastly, you can follow the Spring <a href="javascript:window.open('https://spring.io/blog');" target="_blank" rel="noopener noreferrer">blog <i class="fa fa-external-link"></i></a>or the project team on Twitter (<a href="javascript:window.open('https://twitter.com/springcentral');" target="_blank" rel="noopener noreferrer">SpringCentral <i class="fa fa-external-link"></i></a>).</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="new-features"><a class="anchor" href="#new-features"></a>6. New &amp; Noteworthy</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="new-features.2-2-0"><a class="anchor" href="#new-features.2-2-0"></a>6.1. What’s new in Spring Vault 2.2</h3>
<div class="ulist">
<ul>
<li> <p>Support for Key-Value v2 (versioned backend) secrets through <code class="notranslate">@VaultPropertySource</code>.</p> </li>
<li> <p>SpEL support in <code class="notranslate">@Secret</code>.</p> </li>
<li> <p>Add support for Jetty as reactive HttpClient.</p> </li>
<li> <p><code class="notranslate">LifecycleAwareSessionManager</code> and <code class="notranslate">ReactiveLifecycleAwareSessionManager</code> emit now <code class="notranslate">AuthenticationEvent</code>s.</p> </li>
<li> <p><a href="#vault.authentication.pcf">PCF authentication</a>.</p> </li>
<li> <p>Deprecation of <code class="notranslate">AppIdAuthentication</code>. Use <code class="notranslate">AppRoleAuthentication</code> instead as recommended by HashiCorp Vault.</p> </li>
<li> <p><code class="notranslate">CubbyholeAuthentication</code> and wrapped <code class="notranslate">AppRoleAuthentication</code> now use <code class="notranslate">sys/wrapping/unwrap</code> endpoints by default.</p> </li>
<li> <p>Kotlin Coroutines support for <code class="notranslate">ReactiveVaultOperations</code>.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.2-1-0"><a class="anchor" href="#new-features.2-1-0"></a>6.2. What’s new in Spring Vault 2.1</h3>
<div class="ulist">
<ul>
<li> <p><a href="#vault.authentication.gcpgce">GCP Compute</a>, <a href="#vault.authentication.gcpiam">GCP IAM</a>, and <a href="#vault.authentication.azuremsi">Azure</a> authentication.</p> </li>
<li> <p>Template API support for versioned and unversioned Key/Value backends and for Vault wrapping operations.</p> </li>
<li> <p>Support full pull mode in reactive AppRole authentication.</p> </li>
<li> <p>Improved Exception hierarchy for Vault login failures.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.2-0-0"><a class="anchor" href="#new-features.2-0-0"></a>6.3. What’s new in Spring Vault 2.0</h3>
<div class="ulist">
<ul>
<li> <p>Authentication steps DSL to <a href="#vault.authentication.steps">compose authentication flows</a>.</p> </li>
<li> <p><a href="#vault.core.reactive.template">Reactive Vault client</a> via <code class="notranslate">ReactiveVaultOperations</code>.</p> </li>
<li> <p><a href="#vault.repositories">Vault repository support</a> based on Spring Data KeyValue.</p> </li>
<li> <p>Transit batch encrypt and decrypt support.</p> </li>
<li> <p>Policy management for policies stored as JSON.</p> </li>
<li> <p>Support CSR signing, certificate revocation and CRL retrieval.</p> </li>
<li> <p><a href="#vault.authentication.kubernetes">Kubernetes authentication</a>.</p> </li>
<li> <p>RoleId/SecretId unwrapping for <a href="#vault.authentication.approle">AppRole authentication</a>.</p> </li>
<li> <p><a href="#vault.misc.spring-security">Spring Security integration</a> with transit backend-based <code class="notranslate">BytesKeyGenerator</code> and <code class="notranslate">BytesEncryptor</code>.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-1-0"><a class="anchor" href="#new-features.1-1-0"></a>6.4. What’s new in Spring Vault 1.1.0</h3>
<div class="ulist">
<ul>
<li> <p><a href="#vault.authentication.awsiam">AWS IAM authentication</a>.</p> </li>
<li> <p>Configuration of encryption/decryption versions for transit keys.</p> </li>
<li> <p>Pull mode for <a href="#vault.authentication.approle">AppRole authentication</a>.</p> </li>
<li> <p>Transit batch encrypt and decrypt support.</p> </li>
<li> <p>TTL-based generic secret rotation.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="new-features.1-0-0"><a class="anchor" href="#new-features.1-0-0"></a>6.5. What’s new in Spring Vault 1.0</h3>
<div class="ulist">
<ul>
<li> <p>Initial Vault support.</p> </li>
</ul>
</div>
</div>
</div>
</div>
<h2 id="reference-documentation" class="sect0"><a class="anchor" href="#reference-documentation"></a>Reference documentation</h2>
<div class="sect1">
<h2 id="vault.core"><a class="anchor" href="#vault.core"></a>7. Vault support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Vault support contains a wide range of features which are summarized below.</p>
</div>
<div class="ulist">
<ul>
<li> <p>Spring configuration support using Java based @Configuration classes</p> </li>
<li> <p><code class="notranslate">VaultTemplate</code> helper class that increases productivity performing common Vault operations. Includes integrated object mapping between Vault responses and POJOs.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>For most tasks, you will find yourself using <code class="notranslate">VaultTemplate</code> that leverages the rich communication functionality. <code class="notranslate">VaultTemplate</code> is the place to look for accessing functionality such as reading data from Vault or issuing administrative commands. <code class="notranslate">VaultTemplate</code> also provides callback methods so that it is easy for you to get a hold of the low-level API artifacts such as <code class="notranslate">RestTemplate</code> to communicate directly with Vault.</p>
</div>
<div class="sect2">
<h3 id="dependencies"><a class="anchor" href="#dependencies"></a>7.1. Dependencies</h3>
<div class="paragraph">
<p>The easiest way to find compatible versions of Spring Vault dependencies is by relying on the Spring Vault BOM we ship with the compatible versions defined. In a Maven project you would declare this dependency in the <code class="notranslate">&lt;dependencyManagement /&gt;</code> section of your <code class="notranslate">pom.xml</code>:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 1. Using the Spring Vault BOM
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.vault&lt;/groupId&gt;
      &lt;artifactId&gt;spring-vault-dependencies&lt;/artifactId&gt;
      &lt;version&gt;2.2.2.RELEASE&lt;/version&gt;
      &lt;scope&gt;import&lt;/scope&gt;
      &lt;type&gt;pom&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;</code></pre>
</div>
</div>
</div>
</div>
<div id="dependencies.names" class="paragraph">
<p>The current version is <code class="notranslate">2.2.2.RELEASE</code>. The version name follows the following pattern: <code class="notranslate">${version}-${release}</code> where release can be one of the following:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">BUILD-SNAPSHOT</code> - current snapshots</p> </li>
<li> <p><code class="notranslate">M1</code>, <code class="notranslate">M2</code> etc. - milestones</p> </li>
<li> <p><code class="notranslate">RC1</code>, <code class="notranslate">RC2</code> etc. - release candidates</p> </li>
<li> <p><code class="notranslate">RELEASE</code> - GA release</p> </li>
<li> <p><code class="notranslate">SR1</code>, <code class="notranslate">SR2</code> etc. - service releases</p> </li>
</ul>
</div>
<div class="exampleblock">
<div class="title">
Example 2. Declaring a dependency to Spring Vault
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.springframework.vault&lt;/groupId&gt;
        &lt;artifactId&gt;spring-vault-core&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="dependencies.spring-framework"><a class="anchor" href="#dependencies.spring-framework"></a>7.2. Spring Framework</h3>
<div class="paragraph">
<p>The current version of Spring Vault requires Spring Framework in version 5.2.4.RELEASE or better. The modules might also work with an older bugfix version of that minor version. However, using the most recent version within that generation is highly recommended.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.getting-started"><a class="anchor" href="#vault.core.getting-started"></a>8. Getting Started</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Vault support requires Vault 0.6 or higher and Java SE 6 or higher. An easy way to bootstrap setting up a working environment is to create a Spring based project in <a href="javascript:window.open('https://spring.io/tools/sts');" target="_blank" rel="noopener noreferrer">STS <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>First you need to set up a running Vault server. Refer to the <a href="javascript:window.open('https://www.vaultproject.io/intro/');" target="_blank" rel="noopener noreferrer">Vault <i class="fa fa-external-link"></i></a> for an explanation on how to startup a Vault instance.</p>
</div>
<div class="paragraph">
<p>To create a Spring project in STS go to File → New → Spring Template Project → Simple Spring Utility Project → press Yes when prompted. Then enter a project and a package name such as <code class="notranslate">org.spring.vault.example</code>.</p>
</div>
<div class="paragraph">
<p>Then add the following to <code class="notranslate">pom.xml</code> dependencies section.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 3. Adding Spring Vault dependency
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencies&gt;

  &lt;!-- other dependency elements omitted --&gt;

  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.vault&lt;/groupId&gt;
    &lt;artifactId&gt;spring-vault-core&lt;/artifactId&gt;
    &lt;version&gt;2.2.2.RELEASE&lt;/version&gt;
  &lt;/dependency&gt;

&lt;/dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>If you are using a milestone or release candidate, you will also need to add the location of the Spring Milestone repository to your maven <code class="notranslate">pom.xml</code> which is at the same level of your <code class="notranslate">&lt;dependencies/&gt;</code> element.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories&gt;
  &lt;repository&gt;
    &lt;id&gt;spring-milestone&lt;/id&gt;
    &lt;name&gt;Spring Maven MILESTONE Repository&lt;/name&gt;
    &lt;url&gt;https://repo.spring.io/libs-milestone&lt;/url&gt;
  &lt;/repository&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The repository is also <a href="javascript:window.open('https://repo.spring.io/milestone/org/springframework/vault/');" target="_blank" rel="noopener noreferrer">browseable here <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>If you are using a SNAPSHOT, you will also need to add the location of the Spring Snapshot repository to your maven <code class="notranslate">pom.xml</code> which is at the same level of your <code class="notranslate">&lt;dependencies/&gt;</code> element.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;repositories&gt;
  &lt;repository&gt;
    &lt;id&gt;spring-snapshot&lt;/id&gt;
    &lt;name&gt;Spring Maven SNAPSHOT Repository&lt;/name&gt;
    &lt;url&gt;https://repo.spring.io/libs-snapshot&lt;/url&gt;
  &lt;/repository&gt;
&lt;/repositories&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The repository is also <a href="javascript:window.open('https://repo.spring.io/snapshot/org/springframework/vault/');" target="_blank" rel="noopener noreferrer">browseable here <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>Create a simple <code class="notranslate">Secrets</code> class to persist:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 4. Mapped data object
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package org.spring.vault.example;

public class Secrets {

    String username;
    String password;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>And a main application to run</p>
</div>
<div class="exampleblock">
<div class="title">
Example 5. Example application using Spring Vault
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">package org.springframework.vault.example;

import org.springframework.vault.authentication.TokenAuthentication;
import org.springframework.vault.client.VaultEndpoint;
import org.springframework.vault.core.VaultTemplate;
import org.springframework.vault.support.VaultResponseSupport;

public class VaultApp {

    public static void main(String[] args) {

        VaultTemplate vaultTemplate = new VaultTemplate(new VaultEndpoint(),
                new TokenAuthentication("00000000-0000-0000-0000-000000000000"));

        Secrets secrets = new Secrets();
        secrets.username = "hello";
        secrets.password = "world";

        vaultTemplate.write("secret/myapp", secrets);

        VaultResponseSupport&lt;Secrets&gt; response = vaultTemplate.read("secret/myapp", Secrets.class);
        System.out.println(response.getData().getUsername());

        vaultTemplate.delete("secret/myapp");
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Even in this simple example, there are few things to take notice of</p>
</div>
<div class="ulist">
<ul>
<li> <p>You can instantiate the central class of Spring Vault, <a href="#vault.core.template"><code class="notranslate">VaultTemplate</code></a>, using the <code class="notranslate">org.springframework.vault.client.VaultEndpoint</code> object and the <code class="notranslate">ClientAuthentication</code>. You are not required to spin up a Spring Context to use Spring Vault.</p> </li>
<li> <p>Vault is expected to be configured with a root token of <code class="notranslate">00000000-0000-0000-0000-000000000000</code> to run this application.</p> </li>
<li> <p>The mapper works against standard POJO objects without the need for any additional metadata (though you can optionally provide that information).</p> </li>
<li> <p>Mapping conventions can use field access. Notice the <code class="notranslate">Secrets</code> class has only getters.</p> </li>
<li> <p>If the constructor argument names match the field names of the stored document, they will be used to instantiate the object.</p> </li>
</ul>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.template"><a class="anchor" href="#vault.core.template"></a>9. Introduction to VaultTemplate</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The class <code class="notranslate">VaultTemplate</code>, located in the package <code class="notranslate">org.springframework.vault.core</code>, is the central class of the Spring’s Vault support providing a rich feature set to interact with Vault. The template offers convenience operations to read, write and delete data in Vault and provides a mapping between your domain objects and Vault data.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Once configured, <code class="notranslate">VaultTemplate</code> is thread-safe and can be reused across multiple instances. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The mapping between Vault documents and domain classes is done by delegating to <code class="notranslate">RestTemplate</code>. Spring Web support provides the mapping infrastructure.</p>
</div>
<div class="paragraph">
<p>The <code class="notranslate">VaultTemplate</code> class implements the interface <code class="notranslate">VaultOperations</code>. In as much as possible, the methods on <code class="notranslate">VaultOperations</code> are named after methods available on the Vault API to make the API familiar to existing Vault developers who are used to the API and CLI. For example, you will find methods such as "write", "delete", "read", and "revoke". The design goal was to make it as easy as possible to transition between the use of the Vault API and <code class="notranslate">VaultOperations</code>. A major difference in between the two APIs is that <code class="notranslate">VaultOperations</code> can be passed domain objects instead of JSON Key-Value pairs.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The preferred way to reference the operations on <code class="notranslate">VaultTemplate</code> instance is via its interface <code class="notranslate">VaultOperations</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>While there are many convenience methods on <code class="notranslate">VaultTemplate</code> to help you easily perform common tasks if you should need to access the Vault API directly to access functionality not explicitly exposed by the <code class="notranslate">VaultTemplate</code> you can use one of several execute callback methods to access underlying APIs. The execute callbacks will give you a reference to a <code class="notranslate">RestOperations</code> object. Please see the section <a href="#vault.core.executioncallback">Execution Callbacks</a> for more information.</p>
</div>
<div class="paragraph">
<p>Now let’s look at a examples of how to work with Vault in the context of the Spring container.</p>
</div>
<div class="sect2">
<h3 id="vault.core.template.beans"><a class="anchor" href="#vault.core.template.beans"></a>9.1. Registering and configuring Spring Vault beans</h3>
<div class="paragraph">
<p>Using Spring Vault does not require a Spring Context. However, instances of <code class="notranslate">VaultTemplate</code> and <code class="notranslate">SessionManager</code> registered inside a managed context will participate in <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html#beans-factory-nature');" target="_blank" rel="noopener noreferrer">lifecycle events <i class="fa fa-external-link"></i></a> provided by the Spring IoC container. This is useful to dispose active Vault sessions upon application shutdown. You also benefit from reusing the same <code class="notranslate">VaultTemplate</code> instance across your application.</p>
</div>
<div class="paragraph">
<p>Spring Vault comes with a supporting configuration class that provides bean definitions for use inside a Spring context. Application configuration classes typically extend from <code class="notranslate">AbstractVaultConfiguration</code> and are required to provide additional details that are environment specific.</p>
</div>
<div class="paragraph">
<p>Extending from <code class="notranslate">AbstractVaultConfiguration</code> requires to implement ` VaultEndpoint vaultEndpoint()` and <code class="notranslate">ClientAuthentication clientAuthentication()</code> methods.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 6. Registering Spring Vault objects using Java based bean metadata
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    /**
     * Specify an endpoint for connecting to Vault.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return new VaultEndpoint();                            <i class="conum" data-value="1"></i><b>(1)</b>
    }

    /**
     * Configure a client authentication.
     * Please consider a more secure authentication method
     * for production use.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");                   <i class="conum" data-value="2"></i><b>(2)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Create a new <code class="notranslate">VaultEndpoint</code> that points by default to <code class="notranslate">https://localhost:8200</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>This sample uses <code class="notranslate">TokenAuthentication</code> to get started quickly. See <a href="#vault.core.authentication">Authentication Methods</a> for details on supported authentication methods.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 7. Registering Spring Vault applying injected properties
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    @Value("${vault.uri}")
    URI vaultUri;

    /**
     * Specify an endpoint that was injected as URI.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.from(vaultUri);                          <i class="conum" data-value="1"></i><b>(1)</b>
    }

    /**
     * Configure a Client Certificate authentication.
     * {@link RestOperations} can be obtained from {@link #restOperations()}.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new ClientCertificateAuthentication(restOperations()); <i class="conum" data-value="2"></i><b>(2)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td><code class="notranslate">VaultEndpoint</code> can be constructed using various factory methods such as <code class="notranslate">from(URI uri)</code> or <code class="notranslate">VaultEndpoint.create(String host, int port)</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Dependencies for <code class="notranslate">ClientAuthentication</code> methods can be obtained either from <code class="notranslate">AbstractVaultConfiguration</code> or provided by your configuration.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Creating a custom configuration class might be cumbersome in some cases. Take a look at <code class="notranslate">EnvironmentVaultConfiguration</code> that allows configuration by using properties from existing property sources and Spring’s <code class="notranslate">Environment</code>. Read more in <a href="#vault.core.environment-vault-configuration">Using <code class="notranslate">EnvironmentVaultConfiguration</code></a>. </td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.template.sessionmanagement"><a class="anchor" href="#vault.core.template.sessionmanagement"></a>9.2. Session Management</h3>
<div class="paragraph">
<p>Spring Vault requires a <code class="notranslate">ClientAuthentication</code> to login and access Vault. See <a href="#vault.core.authentication">Authentication Methods</a> on details regarding authentication. Vault login should not occur on each authenticated Vault interaction but must be reused throughout a session. This aspect is handled by a <code class="notranslate">SessionManager</code> implementation. A <code class="notranslate">SessionManager</code> decides how often it obtains a token, about revocation and renewal. Spring Vault comes with two implementations:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">SimpleSessionManager</code>: Just obtains tokens from the supplied <code class="notranslate">ClientAuthentication</code> without refresh and revocation</p> </li>
<li> <p><code class="notranslate">LifecycleAwareSessionManager</code>: This <code class="notranslate">SessionManager</code> schedules token renewal if a token is renewable and revoke a login token on disposal. Renewal is scheduled with an <code class="notranslate">AsyncTaskExecutor</code>. <code class="notranslate">LifecycleAwareSessionManager</code> is configured by default if using <code class="notranslate">AbstractVaultConfiguration</code>.</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.environment-vault-configuration"><a class="anchor" href="#vault.core.environment-vault-configuration"></a>9.3. Using <code class="notranslate">EnvironmentVaultConfiguration</code></h3>
<div class="paragraph">
<p>Spring Vault includes <code class="notranslate">EnvironmentVaultConfiguration</code> configure the Vault client from Spring’s <code class="notranslate">Environment</code> and a set of predefined property keys. <code class="notranslate">EnvironmentVaultConfiguration</code> supports frequently applied configurations. Other configurations are supported by deriving from the most appropriate configuration class. Include <code class="notranslate">EnvironmentVaultConfiguration</code> with <code class="notranslate">@Import(EnvironmentVaultConfiguration.class)</code> to existing Java-based configuration classes and supply configuration properties through any of Spring’s <code class="notranslate">PropertySource</code>s.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 8. Using EnvironmentVaultConfiguration with a property file
</div>
<div class="content">
<div class="listingblock">
<div class="title">
Java-based configuration class
</div>
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@PropertySource("vault.properties")
@Import(EnvironmentVaultConfiguration.class)
public class MyConfiguration{
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">
vault.properties
</div>
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-properties hljs" data-lang="properties">vault.uri=https://localhost:8200
vault.token=00000000-0000-0000-0000-000000000000</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><strong>Property keys</strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>Vault URI: <code class="notranslate">vault.uri</code></p> </li>
<li> <p>SSL Configuration</p>
<div class="ulist">
<ul>
<li> <p>Keystore resource: <code class="notranslate">vault.ssl.key-store</code> (optional)</p> </li>
<li> <p>Keystore password: <code class="notranslate">vault.ssl.key-store-password</code> (optional)</p> </li>
<li> <p>Truststore resource: <code class="notranslate">vault.ssl.trust-store</code> (optional)</p> </li>
<li> <p>Truststore password: <code class="notranslate">vault.ssl.trust-store-password</code> (optional)</p> </li>
</ul>
</div> </li>
<li> <p>Authentication method: <code class="notranslate">vault.authentication</code> (defaults to <code class="notranslate">TOKEN</code>, supported authentication methods are: <code class="notranslate">TOKEN</code>, <code class="notranslate">APPID</code>, <code class="notranslate">APPROLE</code>, <code class="notranslate">AWS_EC2</code>, <code class="notranslate">AZURE</code>, <code class="notranslate">CERT</code>, <code class="notranslate">CUBBYHOLE</code>, <code class="notranslate">KUBERNETES</code>)</p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong>Authentication-specific property keys</strong></p>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.token">Token authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>Vault Token: <code class="notranslate">vault.token</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.appid">AppId authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>AppId path: <code class="notranslate">vault.app-id.app-id-path</code> (defaults to <code class="notranslate">app-id</code>)</p> </li>
<li> <p>AppId: <code class="notranslate">vault.app-id.app-id</code></p> </li>
<li> <p>UserId: <code class="notranslate">vault.app-id.user-id</code>. <code class="notranslate">MAC_ADDRESS</code> and <code class="notranslate">IP_ADDRESS</code> use <code class="notranslate">MacAddressUserId</code>, respective <code class="notranslate">IpAddressUserId</code> user id mechanisms. Any other value is used with <code class="notranslate">StaticUserId</code>.</p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.approle">AppRole authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>AppRole path: <code class="notranslate">vault.app-role.app-role-path</code> (defaults to <code class="notranslate">approle</code>)</p> </li>
<li> <p>RoleId: <code class="notranslate">vault.app-role.role-id</code></p> </li>
<li> <p>SecretId: <code class="notranslate">vault.app-role.secret-id</code> (optional)</p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.awsec2">AWS-EC2 authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>AWS EC2 path: <code class="notranslate">vault.aws-ec2.aws-ec2-path</code> (defaults to <code class="notranslate">aws-ec2</code>)</p> </li>
<li> <p>Role: <code class="notranslate">vault.aws-ec2.role</code></p> </li>
<li> <p>RoleId: <code class="notranslate">vault.aws-ec2.role-id</code> (<strong>deprecated:</strong> use <code class="notranslate">vault.aws-ec2.role</code> instead)</p> </li>
<li> <p>Identity Document URL: <code class="notranslate">vault.aws-ec2.identity-document</code> (defaults to <code class="notranslate"><a href="javascript:window.open('http://169.254.169.254/latest/dynamic/instance-identity/pkcs7');" class="bare" target="_blank" rel="noopener noreferrer">http://169.254.169.254/latest/dynamic/instance-identity/pkcs7 <i class="fa fa-external-link"></i></a></code>)</p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.azuremsi">Azure (MSI) authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>Azure MSI path: <code class="notranslate">vault.azure-msi.azure-path</code> (defaults to <code class="notranslate">azure</code>)</p> </li>
<li> <p>Role: <code class="notranslate">vault.azure-msi.role</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.clientcert">TLS certificate authentication</a></strong></p>
</div>
<div class="paragraph">
<p>No configuration options.</p>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.cubbyhole">Cubbyhole authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>Initial Vault Token: <code class="notranslate">vault.token</code></p> </li>
</ul>
</div>
<div class="paragraph">
<p><strong><a href="#vault.authentication.kubernetes">Kubernetes authentication</a></strong></p>
</div>
<div class="ulist">
<ul>
<li> <p>Kubernetes path: <code class="notranslate">vault.kubernetes.kubernetes-path</code> (defaults to <code class="notranslate">kubernetes</code>)</p> </li>
<li> <p>Role: <code class="notranslate">vault.kubernetes.role</code></p> </li>
<li> <p>Path to service account token file: <code class="notranslate">vault.kubernetes.service-account-token-file</code> (defaults to <code class="notranslate">/var/run/secrets/kubernetes.io/serviceaccount/token</code>)</p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.executioncallback"><a class="anchor" href="#vault.core.executioncallback"></a>9.4. Execution callbacks</h3>
<div class="paragraph">
<p>One common design feature of all Spring template classes is that all functionality is routed into one of the templates execute callback methods. This helps ensure that exceptions and any resource management that maybe required are performed consistency. While this was of much greater need in the case of JDBC and JMS than with Vault, it still offers a single spot for access and logging to occur. As such, using the execute callback is the preferred way to access the Vault API to perform uncommon operations that we’ve not exposed as methods on <code class="notranslate">VaultTemplate</code>.</p>
</div>
<div class="paragraph">
<p>Here is a list of execute callback methods.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">&lt;T&gt; T</code> <strong>doWithVault</strong> <code class="notranslate">(RestOperationsCallback&lt;T&gt; callback)</code> Executes the given <code class="notranslate">RestOperationsCallback</code>, allows to interact with Vault using <code class="notranslate">RestOperations</code> without requiring a session.</p> </li>
<li> <p><code class="notranslate">&lt;T&gt; T</code> <strong>doWithSession</strong> <code class="notranslate">(RestOperationsCallback&lt;T&gt; callback)</code> Executes the given <code class="notranslate">RestOperationsCallback</code>, allows to interact with Vault in an authenticated session.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Here is an example that uses the <code class="notranslate">ClientCallback</code> to initialize Vault:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">vaultOperations.doWithVault(new RestOperationsCallback&lt;VaultInitializationResponse&gt;() {

  @Override
  public VaultInitializationResponse doWithRestOperations(RestOperations restOperations) {

    ResponseEntity&lt;VaultInitializationResponse&gt; exchange = restOperations
                       .exchange("/sys/init", HttpMethod.PUT,
                                 new HttpEntity&lt;Object&gt;(request),
                                 VaultInitializationResponse.class);

    return exchange.getBody();
    }
});</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.reactive.template"><a class="anchor" href="#vault.core.reactive.template"></a>10. Introduction to ReactiveVaultTemplate</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section covers basic information on the reactive programming support using Spring Vault.</p>
</div>
<div class="sect2">
<h3 id="10.1.-What-is-Reactive-Programming?">10.1. What is Reactive Programming?</h3>
<div class="paragraph">
<p>In plain terms reactive programming is about non-blocking applications that are asynchronous and event-driven and require a small number of threads to scale vertically (i.e. within the JVM) rather than horizontally (i.e. through clustering).</p>
</div>
<div class="paragraph">
<p>A key aspect of reactive applications is the concept of backpressure which is a mechanism to ensure producers don’t overwhelm consumers. For example in a pipeline of reactive components extending from the database to the HTTP response when the HTTP connection is too slow the data repository can also slow down or stop completely until network capacity frees up.</p>
</div>
</div>
<div class="sect2">
<h3 id="10.2.-Reactive-Vault-Client">10.2. Reactive Vault Client</h3>
<div class="paragraph">
<p>Spring Vault’s reactive client support is built on top of <a href="#vault.authentication.steps">composable authentication steps</a> and Spring’s functional <code class="notranslate">WebClient</code> via Reactor Netty or Jetty, which feature both a fully non-blocking, event-driven HTTP client.</p>
</div>
<div class="paragraph">
<p>It exposes <code class="notranslate">VaultTokenSupplier</code> as supplier of <code class="notranslate">VaultToken</code> to authenticate HTTP requests and <code class="notranslate">ReactiveVaultOperations</code> as the primary entry point. The core configuration of <code class="notranslate">VaultEndpoint</code>, <code class="notranslate">ClientOptions</code> and <a href="#vault.client-ssl">SSL</a> are reused across the various client implementation.</p>
</div>
<div class="paragraph">
<p>The class <code class="notranslate">ReactiveVaultTemplate</code>, located in the package <code class="notranslate">org.springframework.vault.core</code>, is the central class of the Spring’s reactive Vault support providing a rich feature set to interact with Vault. The template offers convenience operations to read, write and delete data in Vault and provides a mapping between your domain objects and Vault data.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Once configured, <code class="notranslate">ReactiveVaultTemplate</code> is thread-safe and can be reused across multiple instances. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The mapping between Vault documents and domain classes is done by delegating to <code class="notranslate">WebClient</code> and its codecs.</p>
</div>
<div class="paragraph">
<p>The <code class="notranslate">ReactiveVaultTemplate</code> class implements the interface <code class="notranslate">ReactiveVaultOperations</code>. In as much as possible, the methods on <code class="notranslate">ReactiveVaultOperations</code> are named after methods available on the Vault API to make the API familiar to existing Vault developers who are used to the API and CLI. For example, you will find methods such as "write", "delete", and "read". The design goal was to make it as easy as possible to transition between the use of the Vault API and <code class="notranslate">ReactiveVaultOperations</code>. A major difference in between the two APIs is that <code class="notranslate">ReactiveVaultOperations</code> can be passed domain objects instead of JSON Key-Value pairs.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The preferred way to reference the operations on <code class="notranslate">ReactiveVaultTemplate</code> instance is via its interface <code class="notranslate">ReactiveVaultOperations</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Functionality not explicitly exposed by the <code class="notranslate">ReactiveVaultTemplate</code> you can use one of several execute callback methods to access underlying APIs. The execute callbacks will give you a reference to a <code class="notranslate">WebClient</code> object. Please see the section <a href="#vault.core.reactive.executioncallback">Execution Callbacks</a> for more information.</p>
</div>
<div class="paragraph">
<p>Now let’s look at a examples of how to work with Vault in the context of the Spring container.</p>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.reactive.template.beans"><a class="anchor" href="#vault.core.reactive.template.beans"></a>10.3. Registering and configuring Spring Vault beans</h3>
<div class="paragraph">
<p>Using Spring Vault does not require a Spring Context. However, instances of <code class="notranslate">ReactiveVaultTemplate</code> and <code class="notranslate">VaultTokenSupplier</code> registered inside a managed context will participate in <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html#beans-factory-nature');" target="_blank" rel="noopener noreferrer">lifecycle events <i class="fa fa-external-link"></i></a> provided by the Spring IoC container. This is useful to dispose active Vault sessions upon application shutdown. You also benefit from reusing the same <code class="notranslate">ReactiveVaultTemplate</code> instance across your application.</p>
</div>
<div class="paragraph">
<p>Spring Vault comes with a supporting configuration class that provides bean definitions for use inside a Spring context. Application configuration classes typically extend from <code class="notranslate">AbstractVaultConfiguration</code> and are required to provide additional details that are environment specific.</p>
</div>
<div class="paragraph">
<p>Extending from <code class="notranslate">AbstractVaultConfiguration</code> requires to implement ` VaultEndpoint vaultEndpoint()` and <code class="notranslate">ClientAuthentication clientAuthentication()</code> methods.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 9. Registering Spring Vault objects using Java based bean metadata
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
public class AppConfig extends AbstractReactiveVaultConfiguration {

    /**
     * Specify an endpoint for connecting to Vault.
     */
    @Override
    public VaultEndpoint vaultEndpoint() {
        return new VaultEndpoint();                            <i class="conum" data-value="1"></i><b>(1)</b>
    }

    /**
     * Configure a client authentication.
     * Please consider a more secure authentication method
     * for production use.
     */
    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");                   <i class="conum" data-value="2"></i><b>(2)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Create a new <code class="notranslate">VaultEndpoint</code> that points by default to <code class="notranslate">https://localhost:8200</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>This sample uses <code class="notranslate">TokenAuthentication</code> to get started quickly. See <a href="#vault.core.authentication">Authentication Methods</a> for details on supported authentication methods.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.reactive.template.sessionmanagement"><a class="anchor" href="#vault.core.reactive.template.sessionmanagement"></a>10.4. Session Management</h3>
<div class="paragraph">
<p>Spring Vault requires a token to authenticate Vault requests. See <a href="#vault.core.authentication">Authentication Methods</a> on details regarding authentication. The reactive client requires a non-blocking token supplier whose contract is defined in <code class="notranslate">VaultTokenSupplier</code>. Tokens can be static or obtained through a <a href="#vault.authentication.steps">declared authentication flow</a>. Vault login should not occur on each authenticated Vault interaction but the session token should be kept across a session. This aspect is handled by a session manager implementing <code class="notranslate">ReactiveSessionManager</code>, such as <code class="notranslate">ReactiveLifecycleAwareSessionManager</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="vault.core.reactive.executioncallback"><a class="anchor" href="#vault.core.reactive.executioncallback"></a>10.5. Execution callbacks</h3>
<div class="paragraph">
<p>One common design feature of all Spring template classes is that all functionality is routed into one of the templates execute callback methods. This helps ensure that exceptions and any resource management that maybe required are performed consistency. While this was of much greater need in the case of JDBC and JMS than with Vault, it still offers a single spot for access and logging to occur. As such, using the execute callback is the preferred way to access the Vault API to perform uncommon operations that we’ve not exposed as methods on <code class="notranslate">ReactiveVaultTemplate</code>.</p>
</div>
<div class="paragraph">
<p>Here is a list of execute callback methods.</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">&lt;T&gt; T</code> <strong>doWithVault</strong> <code class="notranslate">(Function&lt;WebClient, ? extends T&gt; clientCallback)</code> Composes a reactive sequence the given <code class="notranslate">WebClient</code>, allows to interact with Vault without a session context.</p> </li>
<li> <p><code class="notranslate">&lt;T&gt; T</code> <strong>doWithSession</strong> <code class="notranslate">(Function&lt;WebClient, ? extends T&gt; clientCallback)</code> Composes a reactive sequence the given <code class="notranslate">WebClient</code>, allows to interact with Vault in an authenticated session.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Here is an example that uses the callback to initialize Vault:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">reactiveVaultOperations.doWithVault(webClient -&gt; {

    return webClient.put()
                    .uri("/sys/init")
                    .syncBody(request)
                    .retrieve()
                    .toEntity(VaultInitializationResponse.class);
});</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.propertysupport"><a class="anchor" href="#vault.core.propertysupport"></a>11. Vault Property Source Support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vault can be used in many different ways. One specific use-case is using Vault to store encrypted properties. Spring Vault supports Vault as property source to obtain configuration properties using Spring’s <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html#beans-property-source-abstraction');" target="_blank" rel="noopener noreferrer">PropertySource abstraction <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> You can reference properties stored inside Vault in other property sources or use value injection with <code class="notranslate">@Value(…)</code>. Special attention is required when bootstrapping beans that require data stored inside of Vault. A <code class="notranslate">VaultPropertySource</code> must be initialized at that time to retrieve properties from Vault. </td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring Boot/Spring Cloud users can benefit from <a href="javascript:window.open('https://github.com/spring-cloud/spring-cloud-vault-config');" target="_blank" rel="noopener noreferrer">Spring Cloud Vault <i class="fa fa-external-link"></i></a>'s configuration integration that initializes various property sources during application startup. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="11.1.-Registering-VaultPropertySource">11.1. Registering <code class="notranslate">VaultPropertySource</code></h3>
<div class="paragraph">
<p>Spring Vault provides a <code class="notranslate">VaultPropertySource</code> to be used with Vault to obtain properties. It uses the nested <code class="notranslate">data</code> element to expose properties stored and encrypted in Vault.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">ConfigurableApplicationContext ctx = new GenericApplicationContext();
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
sources.addFirst(new VaultPropertySource(vaultTemplate, "secret/my-application"));</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>In the code above, <code class="notranslate">VaultPropertySource</code> has been added with highest precedence in the search. If it contains a ´foo` property, it will be detected and returned ahead of any <code class="notranslate">foo</code> property in any other <code class="notranslate">PropertySource</code>. <code class="notranslate">MutablePropertySources</code> exposes a number of methods that allow for precise manipulation of the set of property sources.</p>
</div>
</div>
<div class="sect2">
<h3 id="11.2.-@VaultPropertySource">11.2. @VaultPropertySource</h3>
<div class="paragraph">
<p>The <code class="notranslate">@VaultPropertySource</code> annotation provides a convenient and declarative mechanism for adding a <code class="notranslate">PropertySource</code> to Spring’s <code class="notranslate">Environment</code> to be used in conjunction with <code class="notranslate">@Configuration</code> classes.</p>
</div>
<div class="paragraph">
<p><code class="notranslate">@VaultPropertySource</code> takes a Vault path such as <code class="notranslate">secret/my-application</code> and exposes the data stored at the node in a <code class="notranslate">PropertySource</code>. <code class="notranslate">@VaultPropertySource</code> supports lease renewal for secrets associated with a lease (i. e. credentials from the <code class="notranslate">mysql</code> backend) and credential rotation upon terminal lease expiration. Lease renewal is disabled by default.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 10. Properties stored in Vault
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-json hljs" data-lang="json">{
  // …

  "data": {
    "database": {
      "password": ...
    },
    "user.name": ...,
  }

  // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 11. Declaring a
<code class="notranslate">@VaultPropertySource</code>
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@VaultPropertySource("secret/my-application")
public class AppConfig {

    @Autowired Environment env;

    @Bean
    public TestBean testBean() {
        TestBean testBean = new TestBean();
        testBean.setUser(env.getProperty("user.name"));
        testBean.setPassword(env.getProperty("database.password"));
        return testBean;
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 12. Declaring a
<code class="notranslate">@VaultPropertySource</code> with credential rotation and prefix
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@VaultPropertySource(value = "aws/creds/s3-access",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
  // provides aws.access_key and aws.secret_key properties
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Secrets obtained from <code class="notranslate">generic</code> secret backends are associated with a TTL (<code class="notranslate">refresh_interval</code>) but not a lease Id. Spring Vault’s <code class="notranslate">PropertySource</code> rotates generic secrets when reaching its TTL. </td>
</tr>
</tbody>
</table>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> You can use <code class="notranslate">@VaultPropertySource</code> to obtain the newest secret version from the versioned Key-Value backend. Make sure to not include the <code class="notranslate">data/</code> segment in the path. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Any <code class="notranslate">${…}</code> placeholders present in a <code class="notranslate">@VaultPropertySource</code> path are resolved against the set of property sources already registered against the environment, as the following example shows:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 13. Declaring a
<code class="notranslate">@VaultPropertySource</code> path using placeholders
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@VaultPropertySource(value = "aws/creds/${my.placeholder:fallback/value}",
                     propertyNamePrefix = "aws.",
                     renewal = Renewal.ROTATE)
public class AppConfig {
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Assuming that <code class="notranslate">my.placeholder</code> is present in one of the property sources already registered (for example, system properties or environment variables), the placeholder is resolved to the corresponding value. If not, then <code class="notranslate">fallback/value</code> is used as a default. If no default is specified and a property cannot be resolved, an <code class="notranslate">IllegalArgumentException</code> is thrown.</p>
</div>
<div class="paragraph">
<p>In certain situations, it may not be possible or practical to tightly control property source ordering when using <code class="notranslate">@VaultPropertySource</code> annotations. For example, if the <code class="notranslate">@Configuration</code> classes above were registered via component-scanning, the ordering is difficult to predict. In such cases - and if overriding is important - it is recommended that the user fall back to using the programmatic PropertySource API. See <a href="javascript:window.open('https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/env/ConfigurableEnvironment.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">ConfigurableEnvironment</code> <i class="fa fa-external-link"></i></a> and <a href="javascript:window.open('https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/MutablePropertySources.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">MutablePropertySources</code> <i class="fa fa-external-link"></i></a> for details.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.repositories"><a class="anchor" href="#vault.repositories"></a>12. Vault Repositories</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Working with <code class="notranslate">VaultTemplate</code> and responses mapped to Java classes allows basic data operations like read, write and delete. Vault repositories apply Spring Data’s repository concept on top of Vault. A Vault repository exposes basic CRUD functionality and supports query derivation with predicates constraining the Id property, paging and sorting.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Read more about Spring Data Repositories in the <a href="javascript:window.open('https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories');" target="_blank" rel="noopener noreferrer">Spring Data Commons reference documentation <i class="fa fa-external-link"></i></a>. The reference documentation will give you an introduction to Spring Data repositories. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect2">
<h3 id="vault.repositories.usage"><a class="anchor" href="#vault.repositories.usage"></a>12.1. Usage</h3>
<div class="paragraph">
<p>To access domain entities stored in Vault you can leverage repository support that eases implementing those quite significantly.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 14. Sample Credentials Entity
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Secret
public class Credentials {

  @Id String id;
  String password;
  String socialSecurityNumber;
  Address address;
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>We have a pretty simple domain object here. Note that it has a property named <code class="notranslate">id</code> annotated with <code class="notranslate">org.springframework.data.annotation.Id</code> and a <code class="notranslate">@Secret</code> annotation on its type. Those two are responsible for creating the actual key used to persist the object as JSON inside Vault.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Properties annotated with <code class="notranslate">@Id</code> as well as those named <code class="notranslate">id</code> are considered as the identifier properties. Those with the annotation are favored over others. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>The next step is to declare a repository interface that uses the domain object.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 15. Basic Repository Interface for
<code class="notranslate">Credentials</code> entities
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface CredentialsRepository extends CrudRepository&lt;Credentials, String&gt; {

}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>As our repository extends <code class="notranslate">CrudRepository</code> it provides basic CRUD and query methods. Vault repositories require Spring Data components. Make sure to include <code class="notranslate">spring-data-commons</code> and <code class="notranslate">spring-data-keyvalue</code> artifacts in your class path.</p>
</div>
<div class="paragraph">
<p>The easiest way to achive this, is by setting up dependency management and adding the artifacts to your <code class="notranslate">pom.xml</code>:</p>
</div>
<div class="paragraph">
<p>Then add the following to <code class="notranslate">pom.xml</code> dependencies section.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 16. Using the Spring Data BOM
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependencyManagement&gt;
  &lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
      &lt;artifactId&gt;spring-data-releasetrain&lt;/artifactId&gt;
      &lt;version&gt;Moore-SR5&lt;/version&gt;
      &lt;scope&gt;import&lt;/scope&gt;
      &lt;type&gt;pom&lt;/type&gt;
    &lt;/dependency&gt;
  &lt;/dependencies&gt;
&lt;/dependencyManagement&gt;

&lt;dependencies&gt;

  &lt;!-- other dependency elements omitted --&gt;

  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.vault&lt;/groupId&gt;
    &lt;artifactId&gt;spring-vault-core&lt;/artifactId&gt;
    &lt;version&gt;2.2.2.RELEASE&lt;/version&gt;
  &lt;/dependency&gt;

  &lt;dependency&gt;
    &lt;groupId&gt;org.springframework.data&lt;/groupId&gt;
    &lt;artifactId&gt;spring-data-keyvalue&lt;/artifactId&gt;
    &lt;!-- Version inherited from the BOM --&gt;
  &lt;/dependency&gt;

&lt;/dependencies&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The thing we need in between to glue things together is the according Spring configuration.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 17. JavaConfig for Vault Repositories
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
@EnableVaultRepositories
public class ApplicationConfig {

  @Bean
  public VaultTemplate vaultTemplate() {
    return new VaultTemplate(…);
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Given the setup above we can go on and inject <code class="notranslate">CredentialsRepository</code> into our components.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 18. Access to Person Entities
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Autowired CredentialsRepository repo;

public void basicCrudOperations() {

  Credentials creds = new Credentials("heisenberg", "327215", "AAA-GG-SSSS");
  rand.setAddress(new Address("308 Negra Arroyo Lane", "Albuquerque", "New Mexico", "87104"));

  repo.save(creds);                                        <i class="conum" data-value="1"></i><b>(1)</b>

  repo.findOne(creds.getId());                             <i class="conum" data-value="2"></i><b>(2)</b>

  repo.count();                                            <i class="conum" data-value="3"></i><b>(3)</b>

  repo.delete(creds);                                      <i class="conum" data-value="4"></i><b>(4)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Stores properties of <code class="notranslate">Credentials</code> inside Vault Hash with a key pattern <code class="notranslate">keyspace/id</code>, in this case <code class="notranslate">credentials/heisenberg</code>, in the generic secret backend.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Uses the provided id to retrieve the object stored at <code class="notranslate">keyspace/id</code>.</td>
</tr>
<tr>
 <td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Counts the total number of entities available within the keyspace <em>credentials</em> defined by <code class="notranslate">@Secret</code> on <code class="notranslate">Credentials</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Removes the key for the given object from Vault.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vault.repositories.mapping"><a class="anchor" href="#vault.repositories.mapping"></a>12.2. Object to Vault JSON Mapping</h3>
<div class="paragraph">
<p>Vault repositories store objects in Vault using JSON as interchange format. Object mapping between JSON and the entity is done by <code class="notranslate">VaultConverter</code>. The converter reads and writes <code class="notranslate">SecretDocument</code> that contains the body from a <code class="notranslate">VaultResponse</code>. <code class="notranslate">VaultResponse</code>s are read from Vault and the body is deserialized by Jackson into a <code class="notranslate">Map</code> of <code class="notranslate">String</code> and <code class="notranslate">Object</code>. The default <code class="notranslate">VaultConverter</code> implementation reads the <code class="notranslate">Map</code> with nested values, <code class="notranslate">List</code> and <code class="notranslate">Map</code> objects and converts these to entities and vice versa.</p>
</div>
<div class="paragraph">
<p>Given the <code class="notranslate">Credentials</code> type from the previous sections the default mapping is as follows:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-json hljs" data-lang="json">{
  "_class": "org.example.Credentials",                 <i class="conum" data-value="1"></i><b>(1)</b>
  "password", "327215",                                <i class="conum" data-value="2"></i><b>(2)</b>
  "socialSecurityNumber": "AAA-GG-SSSS",
  "address": {                                         <i class="conum" data-value="3"></i><b>(3)</b>
    "street": "308 Negra Arroyo Lane",
    "city": "Albuquerque",
    "state": "New Mexico",
    "zip":"87104"
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>The <code class="notranslate">_class</code> attribute is included on root level as well as on any nested interface or abstract types.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Simple property values are mapped by path.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Properties of complex types are mapped as nested objects.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The <code class="notranslate">@Id</code> property must be mapped to <code class="notranslate">String</code>. </td>
</tr>
</tbody>
</table>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">
Table 1. Default Mapping Rules
</caption>
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Type</th>
<th class="tableblock halign-left valign-top">Sample</th>
<th class="tableblock halign-left valign-top">Mapped Value</th>
</tr>
</thead>
 <tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Simple Type<br> (eg. String)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">String firstname = "Walter";</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">firstname = "Walter"</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Complex Type<br> (eg. Address)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Address adress = new Address("308 Negra Arroyo Lane");</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">address: { "street": "308 Negra Arroyo Lane" }</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">List<br> of Simple Type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">List&lt;String&gt; nicknames = asList("walt", "heisenberg");</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">nicknames: ["walt", "heisenberg"]</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Map<br> of Simple Type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Map&lt;String, Integer&gt; atts = asMap("age", 51)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">atts : {"age" : 51}</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">List<br> of Complex Type</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">List&lt;Address&gt; addresses = asList(new Address("308…</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">address: [{ "street": "308 Negra Arroyo Lane" }, …]</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>You can customize the mapping behavior by registering a <code class="notranslate">Converter</code> in <code class="notranslate">VaultCustomConversions</code>. Those converters can take care of converting from/to a type such as <code class="notranslate">LocalDate</code> as well as <code class="notranslate">SecretDocument</code> whereas the first one is suitable for converting simple properties and the last one complex types to their JSON representation. The second option offers full control over the resulting <code class="notranslate">SecretDocument</code>. Writing objects to <code class="notranslate">Vault</code> will delete the content and re-create the whole entry, so not mapped data will be lost.</p>
</div>
</div>
<div class="sect2">
<h3 id="vault.repositories.queries"><a class="anchor" href="#vault.repositories.queries"></a>12.3. Queries and Query Methods</h3>
<div class="paragraph">
<p>Query methods allow automatic derivation of simple queries from the method name. Vault has no query engine but requires direct access of HTTP context paths. Vault query methods translate Vault’s API possibilities to queries. A query method execution lists children under a context path, applies filtering to the Id, optionally limits the Id stream with offset/limit and applies sorting after fetching the results.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 19. Sample Repository Query Method
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface CredentialsRepository extends CrudRepository&lt;Credentials, String&gt; {

  List&lt;Credentials&gt; findByIdStartsWith(String prefix);
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Query methods for Vault repositories support only queries with predicates on the <code class="notranslate">@Id</code> property. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Here’s an overview of the keywords supported for Vault.</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<caption class="title">
Table 2. Supported keywords for query methods
</caption>
<colgroup>
<col>
<col>
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Keyword</th>
<th class="tableblock halign-left valign-top">Sample</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">After</code>, <code class="notranslate">GreaterThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdGreaterThan(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">GreaterThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdGreaterThanEqual(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Before</code>, <code class="notranslate">LessThan</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdLessThan(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">LessThanEqual</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdLessThanEqual(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Between</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdBetween(String from, String to)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">In</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdIn(Collection ids)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">NotIn</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdNotIn(Collection ids)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Like</code>, <code class="notranslate">StartingWith</code>, <code class="notranslate">EndingWith</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdLike(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">NotLike</code>, <code class="notranslate">IsNotLike</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdNotLike(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Containing</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameContaining(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">NotContaining</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstnameNotContaining(String name)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Regex</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdRegex(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">(No keyword)</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findById(String name)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Not</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByIdNot(String id)</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">And</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByLastnameAndFirstname</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Or</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByLastnameOrFirstname</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Is,Equals</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findByFirstname</code>,<code class="notranslate">findByFirstnameIs</code>,<code class="notranslate">findByFirstnameEquals</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">Top,First</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code class="notranslate">findFirst10ByFirstname</code>,<code class="notranslate">findTop5ByFirstname</code></p></td>
</tr>
</tbody>
</table>
<div class="sect3">
<h4 id="12.3.1.-Sorting-and-Paging">12.3.1. Sorting and Paging</h4>
<div class="paragraph">
<p>Query methods support sorting and paging by selecting in memory a sublist (offset/limit) Id’s retrieved from a Vault context path. Sorting has is not limited to a particular field, unlike query method predicates. Unpaged sorting is applied after Id filtering and all resulting secrets are fetched from Vault. This way a query method fetches only results that are also returned as part of the result.</p>
</div>
<div class="paragraph">
<p>Using paging and sorting requires secret fetching before filtering the Id’s which impacts performance. Sorting and paging guarantees to return the same result even if the natural order of Id returned by Vault changes. Therefore, all Id’s are fetched from Vault first, then sorting is applied and afterwards filtering and offset/limiting.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 20. Paging and Sorting Repository
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public interface CredentialsRepository extends PagingAndSortingRepository&lt;Credentials, String&gt; {

  List&lt;Credentials&gt; findTop10ByIdStartsWithOrderBySocialSecurityNumberDesc(String prefix);

  List&lt;Credentials&gt; findByIdStarts(String prefix, Pageable pageRequest);
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.client.support"><a class="anchor" href="#vault.core.client.support"></a>13. Client support</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Spring Vault supports various HTTP clients to access Vault’s HTTP API. Spring Vault uses <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/integration.html#rest-resttemplate');" target="_blank" rel="noopener noreferrer"><code class="notranslate">RestTemplate</code> <i class="fa fa-external-link"></i></a> as primary interface accessing Vault. Dedicated client support originates from <a href="#vault.client-ssl">customized SSL configuration</a> that is scoped only to Spring Vault’s client components.</p>
</div>
<div class="paragraph">
<p>Spring Vault supports following HTTP imperative clients:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Java’s builtin <code class="notranslate">HttpURLConnection</code> (default client)</p> </li>
<li> <p>Apache Http Components</p> </li>
<li> <p>Netty</p> </li>
<li> <p>OkHttp 3</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Spring Vault’s reactive integration supports the following reactive HTTP clients:</p>
</div>
<div class="ulist">
<ul>
<li> <p>Reactor Netty</p> </li>
<li> <p>Jetty</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Using a specific client requires the according dependency to be available on the classpath so Spring Vault can use the available client for communicating with Vault.</p>
</div>
<div class="sect2">
<h3 id="13.1.-Java’s-builtin-HttpURLConnection">13.1. Java’s builtin <code class="notranslate">HttpURLConnection</code></h3>
<div class="paragraph">
<p>Java’s builtin <code class="notranslate">HttpURLConnection</code> is available out-of-the-box without additional configuration. Using <code class="notranslate">HttpURLConnection</code> comes with a limitation regarding SSL configuration. Spring Vault won’t apply <a href="#vault.client-ssl">customized SSL configuration</a> as it would require a deep reconfiguration of the JVM. This configuration would affect all components relying on the default SSL context. Configuring SSL settings using <code class="notranslate">HttpURLConnection</code> requires you providing these settings as System Properties. See <a href="javascript:window.open('https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#InstallationAndCustomization');" target="_blank" rel="noopener noreferrer">Customizing JSSE <i class="fa fa-external-link"></i></a> for further details.</p>
</div>
</div>
<div class="sect2">
<h3 id="13.2.-External-Clients">13.2. External Clients</h3>
<div class="paragraph">
<p>You can use external clients to access Vault’s API. Simply add one of the following dependencies to your project. You can omit the version number if using <a href="#dependencies">Spring Vault’s Dependency BOM</a></p>
</div>
<div class="exampleblock">
<div class="title">
Example 21. Apache Http Components Dependency
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;org.apache.httpcomponents&lt;/groupId&gt;
  &lt;artifactId&gt;httpclient&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Apache HttpClient’s <a href="javascript:window.open('https://hc.apache.org/httpcomponents-client-4.5.x/logging.html');" target="_blank" rel="noopener noreferrer">wire logging <i class="fa fa-external-link"></i></a> can be enabled through logging configuration. Make sure to not accidentally enable wire logging as logs may expose traffic (tokens and secrets) between your application and Vault in plain text. </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 22. Netty Dependency
 </div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.netty&lt;/groupId&gt;
  &lt;artifactId&gt;netty-all&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 23. Square OkHttp 3
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;com.squareup.okhttp3&lt;/groupId&gt;
  &lt;artifactId&gt;okhttp&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 24. Reactor Netty
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;io.projectreactor.netty&lt;/groupId&gt;
  &lt;artifactId&gt;reactor-netty&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 25. Jetty
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-xml hljs" data-lang="xml">&lt;dependency&gt;
  &lt;groupId&gt;org.eclipse.jetty&lt;/groupId&gt;
  &lt;artifactId&gt;jetty-reactive-httpclient&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vault.client-ssl"><a class="anchor" href="#vault.client-ssl"></a>13.3. Vault Client SSL configuration</h3>
<div class="paragraph">
<p>SSL can be configured using <code class="notranslate">SslConfiguration</code> by setting various properties. You can set either <code class="notranslate">javax.net.ssl.trustStore</code> to configure JVM-wide SSL settings or configure <code class="notranslate">SslConfiguration</code> to set SSL settings only for Spring Vault.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">SslConfiguration sslConfiguration = SslConfiguration.create(            <i class="conum" data-value="1"></i><b>(1)</b>
		new FileSystemResource("client-cert.jks"), "changeit".toCharArray(),
		new FileSystemResource("truststore.jks"), "changeit".toCharArray());

SslConfiguration.forTrustStore(new FileSystemResource("keystore.jks"),  <i class="conum" data-value="2"></i><b>(2)</b>
                                      "changeit".toCharArray())

SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"),    <i class="conum" data-value="3"></i><b>(3)</b>
                                      "changeit".toCharArray())

SslConfiguration.forKeyStore(new FileSystemResource("keystore.jks"),    <i class="conum" data-value="4"></i><b>(4)</b>
                                      "changeit".toCharArray(),
                                      KeyConfiguration.of("key-password".toCharArray(),
                                      "my-key-alias"))</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Full configuration.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>Configuring only trust store settings.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Configuring only key store settings.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b class="notranslate">4</b></td>
<td>Configuring only key store settings with providing a key-configuration.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>Please note that providing <code class="notranslate">SslConfiguration</code> can be only applied when either Apache Http Components or the OkHttp client is on your class-path.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.core.authentication"><a class="anchor" href="#vault.core.authentication"></a>14. Authentication Methods</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Different organizations have different requirements for security and authentication. Vault reflects that need by shipping multiple authentication methods. Spring Vault supports multiple authentications mechanisms.</p>
</div>
<div class="sect2">
<h3 id="14.1.-Externalizing-login-credentials">14.1. Externalizing login credentials</h3>
<div class="paragraph">
<p>Obtaining first-time access to a secured system is known as secure introduction. Any client requires ephemeral or permanent credentials to access Vault. Externalizing credentials is a good pattern to keep code maintainability high but comes at a risk of increased disclosure.</p>
</div>
<div class="paragraph">
<p>Disclosure of login credentials to any party allows login to Vault and access secrets that are permitted by the underlying role. Picking the appropriate client authentication and injecting credentials into the application is subject to risk evaluation.</p>
</div>
<div class="paragraph">
<p>Spring’s <a href="javascript:window.open('https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/core.html#beans-property-source-abstraction');" target="_blank" rel="noopener noreferrer">PropertySource abstraction <i class="fa fa-external-link"></i></a> is a natural fit to keep configuration outside the application code. You can use system properties, environment variables or property files to store login credentials. Each approach comes with its own properties. Keep in mind that the command line and environment properties can be introspected with appropriate OS access levels.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 26. Externalizing
<code class="notranslate">vault.token</code> to a properties file
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@PropertySource("configuration.properties")
@Configuration
public class Config extends AbstractVaultConfiguration {

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication(getEnvironment().getProperty("vault.token"));
    }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Spring allows multiple ways to obtain <code class="notranslate">Environment</code>. When using <code class="notranslate">VaultPropertySource</code>, injection via <code class="notranslate">@Autowired Environment environment</code> will not provide the <code class="notranslate">Environment</code> as the environment bean is still in construction and autowiring comes at a later stage. Your configuration class should rather implement <code class="notranslate">ApplicationContextAware</code> and obtain the <code class="notranslate">Environment</code> from <code class="notranslate">ApplicationContext</code>. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>See <a href="javascript:window.open('https://github.com/spring-projects/spring-vault/blob/master/spring-vault-core/src/test/java/org/springframework/vault/demo/SecurePropertyUsage.java');" target="_blank" rel="noopener noreferrer"><code class="notranslate">SecurePropertyUsage.java</code> <i class="fa fa-external-link"></i></a> for a sample on referencing properties in components and other property sources.</p>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.token"><a class="anchor" href="#vault.authentication.token"></a>14.2. Token authentication</h3>
<div class="paragraph">
<p>Tokens are the core method for authentication within Vault. Token authentication requires a static token to be provided.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Token authentication is the default authentication method. If a token is disclosed an unintended party, it gains access to Vault and can access secrets for the intended client. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Typically, Token authentication is used in scenarios in which the token is created and renewed externally (such as <a href="javascript:window.open('https://github.com/hashicorp/vault-service-broker');" target="_blank" rel="noopener noreferrer">HashiCorp Vault service broker <i class="fa fa-external-link"></i></a>). Depending on the actual setup, you may or may not want token renewal and revocation. See <a href="#vault.authentication.session"><code class="notranslate">LifecycleAwareSessionManager</code></a> for details about TTL and token revocation.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        return new TokenAuthentication("…");
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/concepts/tokens.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Tokens <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/token.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the Token auth backend <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.appid"><a class="anchor" href="#vault.authentication.appid"></a>14.3. AppId authentication</h3>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> AppId authentication is deprecated by Vault. Use <a href="#vault.authentication.approle">AppRole authentication</a> instead. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Vault supports <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/app-id.html');" target="_blank" rel="noopener noreferrer">AppId <i class="fa fa-external-link"></i></a> authentication that consists of two hard to guess tokens. The AppId defaults to <code class="notranslate">spring.application.name</code> that is statically configured. The second token is the UserId which is a part determined by the application, usually related to the runtime environment. IP address, Mac address or a Docker container name are good examples. Spring Vault supports IP address, Mac address and static UserId’s (e.g. supplied via System properties). The IP and Mac address are represented as Hex-encoded SHA256 hash.</p>
</div>
<div class="paragraph">
<p>IP address-based UserId’s use the local host’s IP address.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder()
                .appId("myapp")
                .userIdMechanism(new IpAddressUserId())
                .build();

        return new AppIdAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The corresponding command to generate the IP address UserId from a command line is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="notranslate">$ echo -n 192.168.99.1 | sha256sum</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Including the line break of <code class="notranslate">echo</code> leads to a different hash value so make sure to include the <code class="notranslate">-n</code> flag. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>Mac address-based UserId’s obtain their network device from the localhost-bound device. The configuration also allows specifying a <code class="notranslate">network-interface</code> hint to pick the right device. The value of <code class="notranslate">network-interface</code> is optional and can be either an interface name or interface index (0-based).</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AppIdAuthenticationOptions options = AppIdAuthenticationOptions.builder()
                .appId("myapp")
                .userIdMechanism(new MacAddressUserId())
                .build();

        return new AppIdAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>The corresponding command to generate the Mac address UserId from a command line is:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="notranslate">$ echo -n 0AFEDE1234AC | sha256sum</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> The Mac address is specified uppercase and without colons. Including the line break of <code class="notranslate">echo</code> leads to a different hash value so make sure to include the <code class="notranslate">-n</code> flag. </td>
</tr>
</tbody>
</table>
</div>
<div class="sect3">
<h4 id="14.3.1.-Custom-UserId">14.3.1. Custom UserId</h4>
<div class="paragraph">
<p>A more advanced approach lets you implementing your own <code class="notranslate">AppIdUserIdMechanism</code>. This class must be on your classpath and must implement the <code class="notranslate">org.springframework.vault.authentication.AppIdUserIdMechanism</code> interface and the <code class="notranslate">createUserId</code> method. Spring Vault will obtain the UserId by calling <code class="notranslate">createUserId</code> each time it authenticates using AppId to obtain a token.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="title">
MyUserIdMechanism.java
</div>
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">public class MyUserIdMechanism implements AppIdUserIdMechanism {

  @Override
  public String createUserId() {

    String userId = …
    return userId;
  }
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>See also: <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/app-id.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the App ID auth backend <i class="fa fa-external-link"></i></a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.approle"><a class="anchor" href="#vault.authentication.approle"></a>14.4. AppRole authentication</h3>
<div class="paragraph">
<p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/app-id.html');" target="_blank" rel="noopener noreferrer">AppRole <i class="fa fa-external-link"></i></a> allows machine authentication, like the deprecated (since Vault 0.6.1) <a href="#vault.authentication.appid">AppId authentication</a>. AppRole authentication consists of two hard to guess (secret) tokens: RoleId and SecretId.</p>
</div>
<div class="paragraph">
<p>Spring Vault supports AppRole authentication by providing either RoleId only or together with a provided SecretId and fetching RoleId/SecretId from Vault (push and pull modes with response unwrapping).</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
                .roleId(RoleId.provided("…"))
                .secretId(SecretId.wrapped(VaultToken.of("…")))
                .build();

        return new AppRoleAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Spring Vault also support full pull mode: If RoleId and SecretId are not provided, Spring Vault will retrieve them using the role name and an initial token. The initial token may be associated with a TTL and usage limit.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        VaultToken initialToken = VaultToken.of("…");
        AppRoleAuthenticationOptions options = AppRoleAuthenticationOptions.builder()
                .appRole("…")
                .roleId(RoleId.pull(initialToken))
                .secretId(SecretId.pull(initialToken))
                .build();

        return new AppRoleAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>See also: <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/approle.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the AppRole auth backend <i class="fa fa-external-link"></i></a></p>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.awsec2"><a class="anchor" href="#vault.authentication.awsec2"></a>14.5. AWS-EC2 authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/aws-ec2.html');" target="_blank" rel="noopener noreferrer">aws-ec2 <i class="fa fa-external-link"></i></a> auth backend provides a secure introduction mechanism for AWS EC2 instances, allowing automated retrieval of a Vault token. Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). Instead, it treats AWS as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely represents each EC2 instance.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        return new AwsEc2Authentication(restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>AWS-EC2 authentication enables nonce by default to follow the Trust On First Use (TOFU) principle. Any unintended party that gains access to the PKCS#7 identity metadata can authenticate against Vault.</p>
</div>
<div class="paragraph">
<p>During the first login, Spring Vault generates a nonce that is stored in the auth backend aside the instance Id. Re-authentication requires the same nonce to be sent. Any other party does not have the nonce and can raise an alert in Vault for further investigation.</p>
</div>
<div class="paragraph">
<p>The nonce is kept in memory and is lost during application restart.</p>
</div>
<div class="paragraph">
<p>AWS-EC2 authentication roles are optional and default to the AMI. You can configure the authentication role by setting it in <code class="notranslate">AwsEc2AuthenticationOptions</code>.</p>
</div>
<div class="paragraph">
<p>See also: <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/aws-ec2.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the AWS-EC2 auth backend <i class="fa fa-external-link"></i></a></p>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.awsiam"><a class="anchor" href="#vault.authentication.awsiam"></a>14.6. AWS-IAM authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/aws.html');" target="_blank" rel="noopener noreferrer">aws <i class="fa fa-external-link"></i></a> auth backend allows Vault login by using existing AWS IAM credentials.</p>
</div>
<div class="paragraph">
<p>AWS IAM authentication creates a signed HTTP request that is executed by Vault to get the identity of the signer using AWS STS <code class="notranslate">GetCallerIdentity</code> method. AWSv4 signatures require IAM credentials.</p>
</div>
<div class="paragraph">
<p>IAM credentials can be obtained from either the runtime environment or supplied externally. Runtime environments such as AWS-EC2, Lambda and ECS with assigned IAM principals do not require client-specific configuration of credentials but can obtain these from its metadata source.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
                .credentials(new BasicAWSCredentials(…)).build();

        return new AwsIamAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 27. Using AWS-EC2 instance profile as credentials source
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AwsIamAuthenticationOptions options = AwsIamAuthenticationOptions.builder()
                .credentialsProvider(InstanceProfileCredentialsProvider.getInstance()).build();

        return new AwsIamAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">AwsIamAuthentication</code> requires the AWS Java SDK dependency (<code class="notranslate">com.amazonaws:aws-java-sdk-core</code>) as the authentication implementation uses AWS SDK types for credentials and request signing.</p>
</div>
<div class="paragraph">
<p>You can configure the authentication via <code class="notranslate">AwsIamAuthenticationOptions</code>.</p>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/aws.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the AWS auth backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://docs.aws.amazon.com/STS/latest/APIReference/API_GetCallerIdentity.html');" target="_blank" rel="noopener noreferrer">AWS Documentation: STS GetCallerIdentity <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.azuremsi"><a class="anchor" href="#vault.authentication.azuremsi"></a>14.7. Azure (MSI) authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/azure.html');" target="_blank" rel="noopener noreferrer">azure <i class="fa fa-external-link"></i></a> auth backend provides a secure introduction mechanism for Azure VM instances, allowing automated retrieval of a Vault token. Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). Instead, it treats Azure as a Trusted Third Party and uses the managed service identity and instance metadata information that can be bound to a VM instance.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder()
                    .role(…).build();

        return new AzureMsiAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Azure authentication requires details about the VM environment (subscription Id, resource group name, VM name). These details can be either configured through <code class="notranslate">AzureMsiAuthenticationOptionsBuilder</code>. If left unconfigured, <code class="notranslate">AzureMsiAuthentication</code> queries Azure’s instance metadata service to obtain these details.</p>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/azure.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the Azure auth backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/overview');" target="_blank" rel="noopener noreferrer">Azure Documentation: Managed Service Identity <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.gcpgce"><a class="anchor" href="#vault.authentication.gcpgce"></a>14.8. GCP-GCE authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/gcp.html');" target="_blank" rel="noopener noreferrer">gcp <i class="fa fa-external-link"></i></a> auth backend allows Vault login by using existing GCP (Google Cloud Platform) IAM and GCE credentials.</p>
</div>
<div class="paragraph">
<p>GCP GCE (Google Compute Engine) authentication creates a signature in the form of a JSON Web Token (JWT) for a service account. A JWT for a Compute Engine instance is obtained from the GCE metadata service using <a href="javascript:window.open('https://cloud.google.com/compute/docs/instances/verifying-instance-identity');" target="_blank" rel="noopener noreferrer">Instance identification <i class="fa fa-external-link"></i></a>. This API creates a JSON Web Token that can be used to confirm the instance identity.</p>
</div>
<div class="paragraph">
<p>Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). Instead, it treats GCP as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely represents each GCP service account.</p>
</div>
<div class="paragraph">
<p>You can configure the authentication via <code class="notranslate">GcpComputeAuthenticationOptions</code>.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        GcpComputeAuthenticationOptions options = GcpComputeAuthenticationOptions.builder()
				.role(…).build();

		GcpComputeAuthentication authentication = new GcpComputeAuthentication(options,
				restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/gcp.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the GCP auth backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://cloud.google.com/compute/docs/instances/verifying-instance-identity');" target="_blank" rel="noopener noreferrer">GCP Documentation: Verifying the Identity of Instances <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.gcpiam"><a class="anchor" href="#vault.authentication.gcpiam"></a>14.9. GCP-IAM authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/gcp.html');" target="_blank" rel="noopener noreferrer">gcp <i class="fa fa-external-link"></i></a> auth backend allows Vault login by using existing GCP (Google Cloud Platform) IAM and GCE credentials.</p>
</div>
<div class="paragraph">
<p>GCP IAM authentication creates a signature in the form of a JSON Web Token (JWT) for a service account. A JWT for a service account is obtained by calling GCP IAM’s <a href="javascript:window.open('https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt');" target="_blank" rel="noopener noreferrer"><code class="notranslate">projects.serviceAccounts.signJwt</code> <i class="fa fa-external-link"></i></a> API. The caller authenticates against GCP IAM and proves thereby its identity. This Vault backend treats GCP as a Trusted Third Party.</p>
</div>
<div class="paragraph">
<p>IAM credentials can be obtained from either the runtime environment or supplied externally as e.g. JSON. JSON is the preferred form as it carries the project id and service account identifier required for calling <code class="notranslate">projects.serviceAccounts.signJwt</code>.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        GcpIamAuthenticationOptions options = GcpIamAuthenticationOptions.builder()
				.role(…).credential(GoogleCredentials.getApplicationDefault()).build();

		GcpIamAuthentication authentication = new GcpIamAuthentication(options,
				restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">GcpIamAuthenticationOptions</code> requires the Google Cloud Java SDK dependency (<code class="notranslate">com.google.apis:google-api-services-iam</code> and <code class="notranslate">com.google.auth:google-auth-library-oauth2-http</code>) as the authentication implementation uses Google APIs for credentials and JWT signing.</p>
</div>
<div class="paragraph">
<p>You can configure the authentication via <code class="notranslate">GcpIamAuthenticationOptions</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Google credentials require an OAuth 2 token maintaining the token lifecycle. All API is synchronous therefore, <code class="notranslate">GcpIamAuthentication</code> does not support <code class="notranslate">AuthenticationSteps</code> which is required for reactive usage. </td>
</tr>
</tbody>
</table>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/gcp.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the GCP auth backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt');" target="_blank" rel="noopener noreferrer">GCP Documentation: projects.serviceAccounts.signJwt <i class="fa fa-external-link"></i></a><a id="vault.authentication.gcpiam"></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.pcf"><a class="anchor" href="#vault.authentication.pcf"></a>14.10. PCF authentication</h3>
<div class="paragraph">
<p>The <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/pcf.html');" target="_blank" rel="noopener noreferrer">pcf <i class="fa fa-external-link"></i></a> auth backend allows Vault login for PCF instances. It leverages <a href="javascript:window.open('https://content.pivotal.io/blog/new-in-pcf-2-1-app-container-identity-assurance-via-automatic-cert-rotation');" target="_blank" rel="noopener noreferrer">PCF’s App and Container Identity Assurance <i class="fa fa-external-link"></i></a>.</p>
</div>
<div class="paragraph">
<p>PCF authentication uses the instance key and certificate to create a signature that is validated by Vault. If the signature matches, and potentially bound organization/space/application Id’s match, Vault issues an appropriately-scoped token.</p>
</div>
<div class="paragraph">
<p>Instance credentials are available from files at <code class="notranslate">CF_INSTANCE_CERT</code> and <code class="notranslate">CF_INSTANCE_KEY</code> variables.</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        PcfAuthenticationOptions options = PcfAuthenticationOptions.builder()
                .role(…).build();

        PcfAuthentication authentication = new PcfAuthentication(options,
                restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><code class="notranslate">PcfAuthenticationOptions</code> requires the <a href="javascript:window.open('https://www.bouncycastle.org/latest_releases.html');" target="_blank" rel="noopener noreferrer">BouncyCastle <i class="fa fa-external-link"></i></a> library for creating RSA-PSS signatures.</p>
</div>
<div class="paragraph">
<p>You can configure the authentication via <code class="notranslate">PcfAuthenticationOptions</code>.</p>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/pcf.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the PCF auth backend <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.clientcert"><a class="anchor" href="#vault.authentication.clientcert"></a>14.11. TLS certificate authentication</h3>
<div class="paragraph">
<p>The <code class="notranslate">cert</code> auth backend allows authentication using SSL/TLS client certificates that are either signed by a CA or self-signed.</p>
</div>
<div class="paragraph">
<p>To enable <code class="notranslate">cert</code> authentication you need to:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li> <p>Use SSL, see <a href="#vault.client-ssl">Vault Client SSL configuration</a></p> </li>
<li> <p>Configure a Java <code class="notranslate">Keystore</code> that contains the client certificate and the private key</p> </li>
</ol>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {
        return new ClientCertificateAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>See also: <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/cert.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the Cert auth backend <i class="fa fa-external-link"></i></a></p>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.cubbyhole"><a class="anchor" href="#vault.authentication.cubbyhole"></a>14.12. Cubbyhole authentication</h3>
<div class="paragraph">
<p>Cubbyhole authentication uses Vault primitives to provide a secured authentication workflow. Cubbyhole authentication uses tokens as primary login method. An ephemeral token is used to obtain a second, login VaultToken from Vault’s Cubbyhole secret backend. The login token is usually longer-lived and used to interact with Vault. The login token can be retrieved either from a wrapped response or from the <code class="notranslate">data</code> section.</p>
</div>
<div class="paragraph">
<p><strong>Creating a wrapped token</strong></p>
</div>
<div class="admonitionblock note">
<table>
<tbody>
<tr>
<td class="icon"> <i class="fa icon-note" title="Note"></i> </td>
<td class="content"> Response Wrapping for token creation requires Vault 0.6.0 or higher. </td>
</tr>
</tbody>
</table>
</div>
<div class="exampleblock">
<div class="title">
Example 28. Crating and storing tokens
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-shell hljs" data-lang="shell">$ vault token-create -wrap-ttl="10m"
Key                            Value
---                            -----
wrapping_token:                397ccb93-ff6c-b17b-9389-380b01ca2645
wrapping_token_ttl:            0h10m0s
wrapping_token_creation_time:  2016-09-18 20:29:48.652957077 +0200 CEST
wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 29. Wrapped token response usage
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
                .builder()
                .initialToken(VaultToken.of("…"))
                .wrapped()
                .build();

        return new CubbyholeAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><strong>Using stored tokens</strong></p>
</div>
<div class="exampleblock">
<div class="title">
Example 30. Crating and storing tokens
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-shell hljs" data-lang="shell">$ vault token create
Key                    Value
---                    -----
token                  f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819
token_accessor         4eee9bd9-81bb-06d6-af01-723c54a72148
token_duration         0s
token_renewable        false
token_policies         [root]

$ vault token create -use-limit=2 -orphan -no-default-policy -policy=none
Key                    Value
---                    -----
token                  895cb88b-aef4-0e33-ba65-d50007290780
token_accessor         e84b661c-8aa8-2286-b788-f258f30c8325
token_duration         0s
token_renewable        false
token_policies         [none]

$ export VAULT_TOKEN=895cb88b-aef4-0e33-ba65-d50007290780
$ vault write cubbyhole/token token=f9e30681-d46a-cdaf-aaa0-2ae0a9ad0819</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 31. Stored token response usage
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions
                .builder()
                .initialToken(VaultToken.of("…"))
                .path("cubbyhole/token")
                .build();

        return new CubbyholeAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p><strong>Remaining TTL/Renewability</strong></p>
</div>
<div class="paragraph">
<p>Tokens retrieved from Cubbyhole associated with a non-zero TTL start their TTL at the time of token creation. That time is not necessarily identical with application startup. To compensate for the initial delay, Cubbyhole authentication performs a self lookup for tokens associated with a non-zero TTL to retrieve the remaining TTL. Cubbyhole authentication will not self-lookup wrapped tokens without a TTL because a zero TTL indicates there is no TTL associated.</p>
</div>
<div class="paragraph">
<p>Non-wrapped tokens do not provide details regarding renewability and TTL by just retrieving the token. A self-lookup will lookup renewability and the remaining TTL.</p>
</div>
 <div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/concepts/tokens.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Tokens <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/secrets/cubbyhole/index.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Cubbyhole Secret Backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/concepts/response-wrapping.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Response Wrapping <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.kubernetes"><a class="anchor" href="#vault.authentication.kubernetes"></a>14.13. Kubernetes authentication</h3>
<div class="paragraph">
<p>Vault supports since 0.8.3 <a href="javascript:window.open('https://www.vaultproject.io/docs/auth/kubernetes.html');" target="_blank" rel="noopener noreferrer">kubernetes <i class="fa fa-external-link"></i></a>-based authentication using Kubernetes tokens.</p>
</div>
<div class="paragraph">
<p>Using Kubernetes authentication requires a Kubernetes Service Account Token, usually mounted at <code class="notranslate">/var/run/secrets/kubernetes.io/serviceaccount/token</code>. The file contains the token which is read and sent to Vault. Vault verifies its validity using Kubernetes' API during login.</p>
</div>
<div class="paragraph">
<p>Configuring Kubernetes authentication requires at least the role name to be provided:</p>
</div>
<div class="exampleblock">
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">@Configuration
class AppConfig extends AbstractVaultConfiguration {

    // …

    @Override
    public ClientAuthentication clientAuthentication() {

        KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder()
                .role(…).jwtSupplier(…).build();

        return new KubernetesAuthentication(options, restOperations());
    }

    // …
}</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>You can configure the authentication via <code class="notranslate">KubernetesAuthenticationOptions</code>.</p>
</div>
<div class="paragraph">
<p>See also:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://www.vaultproject.io/docs/auth/kubernetes.html');" target="_blank" rel="noopener noreferrer">Vault Documentation: Using the Kubernetes auth backend <i class="fa fa-external-link"></i></a></p> </li>
<li> <p><a href="javascript:window.open('https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/');" target="_blank" rel="noopener noreferrer">Kubernetes Documentation: Configure Service Accounts for Pods <i class="fa fa-external-link"></i></a></p> </li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.steps"><a class="anchor" href="#vault.authentication.steps"></a>14.14. Authentication Steps</h3>
<div class="paragraph">
<p><code class="notranslate">ClientAuthentication</code> objects describe the authentication flow and perform the actual authentication steps. Pre-composed authentications are easy to use and to configure with a tight binding to synchronous execution.</p>
</div>
<div class="paragraph">
<p>The composition of authentication methods and reusing common steps, such as posting login payload to Vault or retrieving authentication input from an HTTP source is not intended with <code class="notranslate">ClientAuthentication</code> objects.</p>
</div>
<div class="paragraph">
<p>Authentication steps provide reusability of common authentication activity. Steps created via <code class="notranslate">AuthenticationSteps</code> describe an authentication flow in a functional style leaving the actual authentication execution to specific executors.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 32. Stored token authentication flow.
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">AuthenticationSteps.just(VaultToken.of(…));                              <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Creates <code class="notranslate">AuthenticationSteps</code> from just a <code class="notranslate">VaultToken</code>.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>A single-step authentication flow can be created from a single input. Flows declaring multiple authentication steps start with a <code class="notranslate">Supplier</code> or <code class="notranslate">HttpRequest</code> that provide an authentication state object which can be used to map or post to Vault for login.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 33. AppRole authentication flow
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">AuthenticationSteps.fromSupplier(                                       <i class="conum" data-value="1"></i><b>(1)</b>

    () -&gt; getAppRoleLogin(options.getRoleId(), options.getSecretId()))  <i class="conum" data-value="2"></i><b>(2)</b>

    .login("auth/{mount}/login", options.getPath());                    <i class="conum" data-value="3"></i><b>(3)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tbody>
<tr>
<td><i class="conum" data-value="1"></i><b class="notranslate">1</b></td>
<td>Start declaring <code class="notranslate">AuthenticationSteps</code> accepting a <code class="notranslate">Supplier&lt;T&gt;</code>. The state object type depends on the <code class="notranslate">Supplier</code> response type which can be mapped in a later step.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b class="notranslate">2</b></td>
<td>The actual <code class="notranslate">Supplier</code> implementation. Creating a <code class="notranslate">Map</code> in this case.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b class="notranslate">3</b></td>
<td>Perform a Vault login by posting the state object (<code class="notranslate">Map</code>) to a Vault endpoint for Vault token creation. Note that template variables are subject to URL escaping.</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="paragraph">
<p>Authentication flows require an executor to perform the actual login. We provide two executors for different execution models:</p>
</div>
<div class="ulist">
<ul>
<li> <p><code class="notranslate">AuthenticationStepsExecutor</code> as a drop-in replacement for synchronous <code class="notranslate">ClientAuthentication</code>.</p> </li>
<li> <p><code class="notranslate">AuthenticationStepsOperator</code> for reactive execution.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Many <code class="notranslate">ClientAuthentication</code>'s come with static factory methods to create <code class="notranslate">AuthenticationSteps</code> for their authentication-specific options:</p>
</div>
<div class="exampleblock">
<div class="title">
Example 34. Synchronous
<code class="notranslate">AuthenticationSteps</code> execution
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">CubbyholeAuthenticationOptions options = …
RestOperations restOperations = …

AuthenticationSteps steps = CubbyholeAuthentication.createAuthenticationSteps(options);

AuthenticationStepsExecutor executor = new AuthenticationStepsExecutor(steps, restOperations);

VaultToken token = executor.login();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="vault.authentication.session"><a class="anchor" href="#vault.authentication.session"></a>14.15. Token Lifecycle</h3>
<div class="paragraph">
<p>Vault’s tokens can be associated with a time to live. Tokens obtained by an authentication method are intended to be used as long as the session is active and should not expire while the application is active.</p>
</div>
<div class="paragraph">
<p>Spring Vault provides with <a href="javascript:window.open('https://docs.spring.io/spring-vault/docs/2.2.2.RELEASE/api/org/springframework/vault/authentication/LifecycleAwareSessionManager.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">LifecycleAwareSessionManager</code> <i class="fa fa-external-link"></i></a> a session manager that can renew the token until it reaches its terminal TTL to then perform another login to obtain the next token which is associated with the session.</p>
</div>
<div class="paragraph">
<p>Depending on the authentication method, a login can create two kinds of tokens:</p>
</div>
<div class="ulist">
<ul>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring-vault/docs/2.2.2.RELEASE/api/org/springframework/vault/support/VaultToken.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">VaultToken</code> <i class="fa fa-external-link"></i></a>: Generic token encapsulating the actual token.</p> </li>
<li> <p><a href="javascript:window.open('https://docs.spring.io/spring-vault/docs/2.2.2.RELEASE/api/org/springframework/vault/support/LoginToken.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">LoginToken</code> <i class="fa fa-external-link"></i></a>: Token associated with renewability/TTL.</p> </li>
</ul>
</div>
<div class="paragraph">
<p>Authentication methods such as <a href="javascript:window.open('https://docs.spring.io/spring-vault/docs/2.2.2.RELEASE/api/org/springframework/vault/authentication/TokenAuthentication.html');" target="_blank" rel="noopener noreferrer"><code class="notranslate">TokenAuthentication</code> <i class="fa fa-external-link"></i></a> just create a <code class="notranslate">VaultToken</code> which does not carry any renewability/TTL details. <code class="notranslate">LifecycleAwareSessionManager</code> will run a self-lookup on the token to retrieve renewability and TTL from Vault. <code class="notranslate">VaultToken</code> are renewed periodically if self-lookup is enabled. Note that <code class="notranslate">VaultToken</code> are never revoked, only <code class="notranslate">LoginToken</code> are revoked.</p>
</div>
<div class="paragraph">
<p>Authentication methods creating <code class="notranslate">LoginToken</code> directly (all login-based authentication methods) already provide all necessary details to setup token renewal. Tokens obtained from a login are revoked by <code class="notranslate">LifecycleAwareSessionManager</code> if the session manager is shut down.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="vault.misc"><a class="anchor" href="#vault.misc"></a>15. Miscellaneous</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Learn in this chapter about details worth mentioning like the Spring Security integration.</p>
</div>
<div class="sect2">
<h3 id="vault.misc.spring-security"><a class="anchor" href="#vault.misc.spring-security"></a>15.1. Spring Security</h3>
<div class="paragraph">
<p>Spring Vault integrates with Spring Security by providing implementations for <a href="javascript:window.open('https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#spring-security-crypto-keygenerators');" target="_blank" rel="noopener noreferrer"><code class="notranslate">BytesKeyGenerator</code> <i class="fa fa-external-link"></i></a> and <a href="javascript:window.open('https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#spring-security-crypto-encryption');" target="_blank" rel="noopener noreferrer"><code class="notranslate">BytesEncryptor</code> <i class="fa fa-external-link"></i></a>. Both implementations use Vault’s <code class="notranslate">transit</code> backend.</p>
</div>
<div class="exampleblock">
<div class="title">
Example 35.
<code class="notranslate">VaultBytesKeyGenerator</code> example
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">VaultOperations operations = …;
VaultBytesKeyGenerator generator = new VaultBytesKeyGenerator(operations);

byte[] key = generator.generateKey();</code></pre>
</div>
</div>
</div>
</div>
<div class="exampleblock">
<div class="title">
Example 36.
<code class="notranslate">VaultBytesEncryptor</code> example
</div>
<div class="content">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight notranslate"><code class="language-java hljs" data-lang="java">VaultTransitOperations transit = …;

VaultBytesEncryptor encryptor = new VaultBytesEncryptor(transit, "my-key-name");

byte[] ciphertext = encryptor.encrypt(plaintext);

byte[] result = encryptor.decrypt(ciphertext);</code></pre>
</div>
</div>
</div>
</div>
<div class="paragraph">
<p>Vault encapsulates an entropy source that is decoupled from your JVM along with server-side key-management. This relieves the burden of proper encryption/decryption from application developers and pushes the burden onto the operators of Vault. Operators of Vault commonly include the security team at an organization, which means they can ensure that data is encrypted/decrypted properly. Additionally, since encrypt/decrypt operations must enter the audit log, any decryption event is recorded.</p>
</div>
<div class="paragraph">
<p>The backend also supports key rotation, which allows a new version of the named key to be generated. All data encrypted with the key will use the newest version of the key; previously encrypted data can be decrypted using old versions of the key. Administrators can control which previous versions of a key are available for decryption, to prevent an attacker gaining an old copy of ciphertext to be able to successfully decrypt it.</p>
</div>
<div class="paragraph">
<p>Vault is after all a networked service that incurs each operation with a latency. Components heavily using encryption or random bytes generation may experience a difference in throughput and performance.</p>
</div>
</div>
</div>
</div></div>
</div>
</section>
<div class="right-sidebar">
<div class="affix"><ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-6108808167664152" data-ad-slot="3102929424" data-ad-format="auto" data-full-width-responsive="true"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script></div>
</div>
</div>
<div class="ft">
<a href="#toolbar-title" id="anchorNavigationExGoTop"><i class="fa fa-arrow-up"></i></a>
<footer class="footer">
<div class="footer__container--normal">
<img alt="扫码关注公众号" title="扫码关注公众号" src="static/picture/qr-code.png" width="170" height="170">
<div class="footer__description--normal">
<p class="paragraph footer__author--normal">Docs4dev<sup class="super">&#xAE;</sup>
</p>
<p class="paragraph footer__quote&#45;&#45;normal">
如果你在使用过程中遇到任何问题，可以在 <a href="javascript:window.open('https://github.com/docs4dev/docs4dev-issues');" target="_blank" rel="noopener noreferrer">这里<i class="fa fa-external-link"></i></a> 提issue。
</p>
<div class="footer__main--normal">
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
<a href="javascript:window.open('https://beian.miit.gov.cn/');">
蜀ICP备14021783号-6
</a>
</p>
<p class="paragraph footer__main__paragraph--normal copyright" style="color: #666 !important;">
Copyright &#xA9; Docs4dev all
right reserved, powered by <a href="index2.html" target="_blank">Docs4dev</a></p>
</div>
</div>
</div>
<div class="box__issues">
</div>
</footer>
</div>
</div>
</div>
</div>
</div>
<script>
  var hasToc = true;
  /*  var downloadable = /!*false*!/ false;
    var editable = /!*false*!/ false;
    var code = /!*"spring-vault"*!/ false;
    var version = /!*"2.2.2.RELEASE"*!/ false;
    var type = /!*"reference"*!/ false;
    var lang = /!*"en"*!/ 'en';
    //edit link
    require(["gitbook", "jQuery"], function (gitbook, $) {
      gitbook.events.bind('start', function (e, config) {
        // Add edit toolbar to left
        var chapterId = /!*16526*!/ 0;
        if (downloadable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-download',
            text: '下载',
            onClick: function () {
              window.open('/download?code=' + code + '&version=' + version + '&type=' + type + '&lang=' + lang);
            }
          });
        }
        if (editable) {
          gitbook.toolbar.createButton({
            icon: 'fa fa-edit',
            text: '编辑此页',
            onClick: function () {
              window.open('/docs/edit?chapterId=' + chapterId + '&lang=' + lang);
            }
          });
        }
      });
    });*/
</script>
<script>
    var code = "spring-vault";
    var lang = "en";
  </script>

<script src="static/js/autocomplete-js.js"></script>
<script src="static/js/app.min.js"></script>
<script src="static/js/search.min.js"></script>
</body>
</html>
